v002/ecriture/

Les écritures se font objet touristique par objet touristique, via ce service d’écriture. Cette page décrit la structure générale d’une requête (hors structure des données touristiques). Des pages annexes décrivent en détail le format des données touristiques.

Si lors de vos essais, vous obtenez un message indiquant une erreur d’authentification, merci de veiller à vérifier le format de votre url pour accéder aux API en écriture, et en particulier si votre url se termine bien avec un ‘/’ (slash).

Chaque appel permet la modification d’un seul objet. Il est cependant possible de modifier dans un même appel un objet et un ou plusieurs de ces aspects.

Formulaire d’envoi des données

Un appel au web-service d’écriture s’articule autour d’un formulaire au format multipart/form-data, notamment pour permettre de manipuler plus facilement les fichiers multimédias.

Le formulaire multipart est décomposé en plusieurs parties. La première contient des informations à portée générale (id de l’objet, type d’actions, etc.), la seconde étant composée d’un ou plusieurs « blocs » de modification.

Dans la suite de cette page, les exemples comme celui-ci indique l’utilisation d’un champ de formulaire multipart/form-data nommé champ et contenant la donnée valeur. De manière générale, les éléments passé en paramètre sont encodés au format JSON.

champ=valeur

N.B : la notion de « bloc » est entièrement logique. Dans le formulaire les différents paramètres sont à plat.

Bloc informations générales

Les paramètres généraux du formulaire sont :

  • mode : une chaîne de caractères. Obligatoire. L’action à réaliser
    • CREATION
    • MODIFICATION
    • DEMANDE_SUPPRESSION
    • DEMANDE_MASQUAGE (depuis 1.36 – juin 2022)
    • ANNULATION_DEMANDE (depuis 1.36 – juin 2022) : permet l’annulation d’une demande d’écriture par API seulement
  • id : un entier. L’identifiant de l’objet, obligatoire pour la modification et la suppression.
  • type : une chaîne de caractères. Le type d’objet créé, obligatoire pour la création (liste des types d’objets ici)
  • fields : une liste de chaînes de caractères au format JSON. La liste des paramètres désignant la racine d’un bloc de modification.
  • skipValidation : une chaîne de caractères représentant un booléen (‘true’ ou ‘false’). ‘true’ pour demander une publication directe des données modifiées si aucune erreur de validation n’a été remontée. Ce paramètre est ignoré pour la suppression ou si le projet ne permet pas la validation directe par sa configuration. Attention : si skipValidation est passé en booléen, Apidae ne renvoie pas d’erreur mais ignore la commande.
  • onValidationFail (depuis 1.36 – juin 2022) : (string) ASK|CANCEL
    Ce champ n’est utile que lorsqu’il est utilisé avec skipValidation=true.
    En cas d’impossibilité de valider l’écriture automatiquement (skipValidation=true) à cause d’une erreur de saisie bloquante (ex: périodes d’ouvertures qui se chevauchent…) :
    • ASK : l’offre ne sera pas validée mais passera en attente de validation sur IHM (CREATION_VALIDATION_ASKED) et sera donc verrouillée/en brouillon jusqu’à une intervention humaine.
    • CANCEL : l’écriture sera annulée : l’offre ne sera donc pas verrouillée/en brouillon.
  • tokenSSO : une chaîne de caractères / GUID. Facultatif. Token généré pour l’utilisateur lors de sa connexion au travers du SSO Apidae (Apidae Connect). Il est donc récupérable aux travers des API de SSO. Si ce paramètre est présent, il est utilisé pour identifier avec certitude l’auteur de la modification faite sur l’objet touristique. S’il ne l’est pas, c’est l’utilisateur par défaut configuré dans le projet d’API en écriture/multi-membres qui est considéré comme étant l’auteur.
    Si le token est faux (aucun utilisateur associé) ou si l’utilisateur identifié n’a pas les droits de modification, l’écriture est rejetée.
    Si le paramètre skipValidation est activé (‘true’) et que l’utilisateur n’a pas le droit « Valideur d’objets », l’écriture est rejetée.
  • proprietaireId : un entier. Facultatif sauf dans le contexte de création d’un objet au travers d’ un projet multi-membres sans tokenSSO. Identifiant du membre qui sera propriétaire de l’objet à créer. Ce membre doit faire partie des membres abonnés au projet. Si le paramètre tokenSSO est renseigné, c’est le membre de l’utilisateur rattaché à ce token qui sera propriétaire de l’objet

Attention à l’utilisation du paramètre skipValidation. Il est fortement recommandé de valider les modifications dans l’application Apidae pour s’assurer qu’elles sont bien cohérentes. Si vous désirez sauter la validation et publier directement vos modifications, faites-le avec précaution : il n’existe pas de moyen de revenir en arrière sur les modifications effectuées sur une fiche.

Blocs de modification

La notion de « bloc de modification » désigne un groupe de paramètres du formulaire qui permettent d’effectuer une modification sur la fiche.

Racine des modifications

La racine est le point à partir duquel on injecte les données JSON dans la fiche.
Chaque bloc est identifié par une racine des modifications dans l’objet (ex : la racine « informationsRestauration.capacite » permet d’injecter des modifications directement dans la section d’un objet de type Restauration).
La mot-clé root permet de prendre pour racine des modifications à la racine de l’objet.

Ainsi, il est possible de regrouper toutes ses modifications dans seul bloc en utilisant le mot clé root ou d’ajouter plusieurs blocs de modifications prenant pour racine différents sections/champs de la fiche.

Exemple 1 : paramètres du formulaire avec deux racines pour deux blocs de modification :

presentation.descriptifCourt={
    "libelleFr" : "Descriptif court FR",
    "libelleNl" : "Descriptif court NL"
}

informationsRestauration.capacite={
    "nombreSalles" : 3,
    "nombreMaximumCouverts" : 75,
    "nombreCouvertsTerrasse" : 30
}

Exemple 2 : la même modification avec un seul paramètre de formulaire en utilisant la racine « root » :

root={
    "type": "RESTAURATION",
    "presentation" : {
        "descriptifCourt" : {
            "libelleFr" : "Descriptif court FR",
            "libelleNl" : "Descriptif court NL"
        }
    },
    "informationsRestauration" : {
        "capacite" : {
            "nombreSalles" : 3,
            "nombreMaximumCouverts" : 75,
            "nombreCouvertsTerrasse" : 30
        }
    }
}

Quand vous fournissez un objet entier (champ root), il est nécessaire de fournir le champ « type » (que ce soit pour une sérialisation ou une désérialisation) de manière à ce que le moteur de désérialisation puisse fonctionner.

Paramètres d’un bloc de modification de la fiche (aspect STANDARD)

La différents paramètres d’un bloc de modification sont tous préfixés par la racine du bloc :

  • root : paramètre contenant les données JSON à injecter.
  • root.fieldList : paramètre obligatoire contenant une liste exhaustive au format JSON des champs de l’objet qui vont être modifiés par ce bloc. Attention, aucun champ en dehors de ceux spécifiés dans cette liste ne sera modifié par ce bloc, même si des données JSON pour ces champs ont été fournies. Ce paramètre sert à contrôler la portée de modification et éviter tout écrasement de données involontaire. Le champ type (d’objet touristique, = ACTIVITE, FETE_ET_MANIFESTATION, …), ne doit pas être présent dans cette liste.

Exemple :

informationsRestauration.capacite={
    "nombreSalles" : 3,
    "nombreMaximumCouverts" : 75,
    "nombreCouvertsTerrasse" : 30
}

informationsRestauration.capacite.fieldList=[
    "informationsRestauration.capacite.nombreSalles",
    "informationsRestauration.capacite.nombreMaximumCouverts",
    "informationsRestauration.capacite.nombreCouvertsTerrasse"
]

Exemple 2 : la même modification en utilisant la racine « root » :

root={
    "type": "RESTAURATION",
    "informationsRestauration" : {
        "capacite" : {
            "nombreSalles" : 3,
            "nombreMaximumCouverts" : 75,
            "nombreCouvertsTerrasse" : 30
        }
    }
},root.fieldList=[
    "informationsRestauration.capacite.nombreSalles",
    "informationsRestauration.capacite.nombreMaximumCouverts",
    "informationsRestauration.capacite.nombreCouvertsTerrasse"
]

Paramètres d’un bloc de modification d’aspect

Un bloc de modification peut modifier un aspect s’il contient les paramètres suivants :

  • aspect.. : paramètre contenant les données JSON à injecter dans l’aspect. Si l’objet ne contient pas d’aspect du type spécifié, un aspect de ce type est créé. Exemple : pour la racine root sur l’aspect HIVER, on utilisera le paramètre aspect.HIVER.root.
  • aspect…fieldList : paramètre obligatoire contenant une liste exhaustive au format JSON des champs de l’aspect qui vont être modifiés parc ce bloc. Ne doit contenir que des champs surchargeables par aspect. Si un champ de cette liste n’est pas déjà surchargé par l’aspect, il sera ajouté au champs surchargés.
  • aspect…removeAspectFields : paramètre facultatif contenant la liste des champs au format JSON qui ne doivent plus être surchargés à l’issue de la modification. Chaque champ de cette liste est retiré de la liste des champs surchargés par l’aspect.

Exemple : ce bloc provoque la surcharge dans l’aspect HIVER des champs informationsRestauration.capacite.nombreSalles, informationsRestauration.capacite.nombreMaximumCouverts, informationsRestauration.capacite.nombreCouvertsTerrasse. Les surcharges des champs informationsRestauration.capacite.descriptionSalles et informationsRestauration.capacite.nombreSallesClimatisees sont supprimées.

aspect.HIVER.informationsRestauration.capacite={
    "nombreSalles" : 3,
    "nombreMaximumCouverts" : 75,
    "nombreCouvertsTerrasse" : 30
}

aspect.HIVER.informationsRestauration.capacite.fieldList=[
    "informationsRestauration.capacite.nombreSalles",
    "informationsRestauration.capacite.nombreMaximumCouverts",
    "informationsRestauration.capacite.nombreCouvertsTerrasse"
]

aspect.HIVER.informationsRestauration.capacite.removeAspectFields=[
    "informationsRestauration.capacite.descriptionSalles"
    "informationsRestauration.capacite.nombreSallesClimatisees",
]

Modes d’utilisation

On distingue trois modes : la création, la modification et la demande de suppression. Un appel ne peut concerner qu’un seul mode à la fois.

Modification

La modification de fiche se fait avec l’action MODIFICATION. En mode modification, le paramètre id est obligatoire pour déterminer sur quelle fiche doivent être réalisées les modifications.

Exemple : le formulaire ci-dessous modifie le descriptif court de la fiche simultanément sur le standard et sur l’aspect HIVER.

mode="MODIFICATION"
id=121013
fields=[ "root", "aspect.HIVER.root" ]
root={ "type" : "EQUIPEMENT", "presentation" : { "descriptifCourt" : { "libelleFr" : "Descriptif court" } } }
root.fieldList=[ "presentation.descriptifCourt" ]
aspect.HIVER.root={ "presentation" : { "descriptifCourt" : { "libelleFr" : "Descriptif court HIVER" } } }
aspect.HIVER.root.fieldList=[ "presentation.descriptifCourt" ]

Certains éléments peuvent interdire la modification d’une offre : brouillons déjà présents, commune non autorisée… Il est possible de vérifier avant la modification s’il sera possible d’écrire sur une offre en particulier.

Création

La création de fiche se fait avec l’action CREATION. En mode modification, le paramètre type est obligatoire pour déterminer le type de la fiche que l’on va créer.
A l’issue d’un appel en création, l’identifiant de la fiche nouvellement créée est envoyé dans la réponse.

Exemple : le formulaire ci-dessous crée une nouvelle fiche de type EQUIPEMENT et lui ajoute un aspect HIVER avec un descriptif court. Notez que les données injectées sont très simplifier pour des raisons de lisibilité de l’exemple, il est conseillé de remplir un maximum d’informations lors de la création d’une fiche.

mode="CREATION"
type="EQUIPEMENT"
fields=[ "root", "aspect.HIVER.root" ]
root={ "type" : "EQUIPEMENT", "nom" : { "libelleFr" : "Nouvel équipement", "libelleEn" : "New equipment" } }
root.fieldList=[ "nom" ]
aspect.HIVER.root={ "presentation" : { "descriptifCourt" : { "libelleFr" : "Descriptif court HIVER" } } }
aspect.HIVER.root.fieldList=[ "presentation.descriptifCourt" ]

Suppression

La demande de suppression d’une fiche se fait avec l’action DEMANDE_SUPPRESSION. Cette action envoi une demande de suppression pour la fiche concernée, elle ne la supprime pas directement.
En mode demande de suppression, le paramètre id est obligatoire et tous les autres paramètres sont ignorés.

Exemple :

mode="DEMANDE_SUPPRESSION"
id=121013

Format des objets touristiques

Le format des données qui doivent être injectées lors d’un appel à l’API d’écriture est très proche de celui disponible en sortie des flux d’API et d’export. Les données sont au format JSON et possède la même structure. Il a cependant été nécessaire d’ajouter quelques informations aux flux de sortie afin de permettre la modification de certaines informations qui n’étaient pas modifiées auparavant.

Apidae – API d’écriture – Format des objets

Manipulation des fichiers multimédias

Il est possible via un appel de manipuler les champs illustrations et multimedias d’une fiche. L’insertion et la modification de multimédias se font via un format dédié.

Apidae – API d’écriture – Multimédias

Format de la réponse

Lorsqu’il n’y a aucune erreur au cours de l’appel, le serveur répond avec un objet JSON contenant les champs suivants :

id

(optionnel)
type : un entier
description : seulement pour création, c’est l’identifiant de la fiche nouvellement créée.

status

type : une chaîne de caractère
description : indique le résultat de l’appel.
valeurs possibles :

  • CREATION_VALIDATION_SKIPPED : la fiche a bien été créée et publiée (aucune erreur de validation)
  • CREATION_VALIDATION_ASKED : la fiche a été créée et est en attente de validation via l’interface de l’application Apidae.
  • MODIFICATION_VALIDATION_SKIPPED : la fiche a bien été modifiée et publiée (aucune erreur de validation)
  • MODIFICATION_VALIDATION_ASKED : la fiche a été modifiée et est en attente de validation via l’interface de l’application Apidae.
  • MODIFICATION_NO_DIFF : les données injectées n’ont apportées aucune modification aux information de l’objet. Son état reste inchangé.
  • DEMANDE_SUPPRESSION_SENT : la demande de suppression de la fiche a bien été envoyée et doit être validée dans l’interface de l’application Apidae.
  • DEMANDE_MASQUAGE_SENT (depuis 1.36 – juin 2022) : La demande de masquage a été prise en compte et doit être validée sur l’interface.
  • CANCEL_DONE (depuis 1.36 – juin 2022) : La DEMANDE_ANNULATION a fonctionné.
  • NO_ACTION : aucune action n’a été réalisée.

message

(optionnel)
type : une chaîne de caractères
description : un message complémentaire pouvant apporter un complément au statut.

Exemple
{
"status" : "MODIFICATION_VALIDATION_ASKED"
}

informations

(optionnel)
disponibilité : depuis 1.36 – juin 2022
type : tableau
description : Lorsqu’un critère est interdit, l’écriture peut quand même fonctionner (code 200) : le tableau « informations » contient alors la liste des critères qui auraient été interdits, avec si possible la raison de l’interdiction.

Exemple
{
    "code": 200,
    "status": "CREATION_VALIDATION_SKIPPED",
    "id": 5901986,
    "informations": [
        {
            "type": "ELEMENT_REFERENCE_INTERDIT",
            "message": "L'\u00e9l\u00e9ment de r\u00e9f\u00e9rence (Plage en b\u00e9ton) n'est pas autoris\u00e9",
            "elementReferenceId": 6428,
            "elementReferenceType": "Environnement"
        },
        {
            "type": "ELEMENT_REFERENCE_INTERDIT",
            "message": "L'\u00e9l\u00e9ment de r\u00e9f\u00e9rence (Dans une r\u00e9serve naturelle) n'est pas autoris\u00e9",
            "elementReferenceId": 4630,
            "elementReferenceType": "Environnement"
        },
        {
            "type": "ELEMENT_REFERENCE_INTERDIT",
            "message": "L'\u00e9l\u00e9ment de r\u00e9f\u00e9rence (Littoral) n'est pas autoris\u00e9",
            "elementReferenceId": 6220,
            "elementReferenceType": "Environnement"
        }
    ]
}

Mon appel échoue : que faire ?

Lorsqu’une erreur s’est produite au cours de la modification, le web-service répond par un code et un message d’erreur qui vous permettra dans la majorité des cas de comprendre pourquoi l’appel à échoué.
Quelques codes d’erreur et leur signification :

  • ECRITURE_FORBIDDEN : vous ne disposez pas de droits suffisant pour modifier l’objet ou le projet ne vous autorise pas à modifier cet objet.
  • ECRITURE_BAD_REQUEST : le formulaire ou son contenu n’ont pas le format attendu. 
  • ECRITURE_INVALID_JSON_DATA : les données JSON à injecter n’ont pas le format attendu.
  • ECRITURE_INVALID_OBJET_TOURISTIQUE_DATA : les données à injecter dans la fiche présentent des incohérences.
  • DEMANDE_MASQUAGE_FAILED (depuis 1.36 – juin 2022) : accompagné du message, indique que la demande de masquage n’a pas été prise en compte (objet déjà en modification…)
  • CREATION_VALIDATION_FAILED, MODIFICATION_VALIDATION_FAILED (depuis 1.36 – juin 2022) : l’écriture a été automatiquement annulée, parce que la validation (skipValidation=true) n’a pas pu être réalisée (erreur de saisie bloquante) : voir onValidationFail.
  • CANCEL_FAILED (depuis 1.36 – juin 2022) : La DEMANDE_ANNULATION n’a pas fonctionné.

Dans tous les cas, le message associé donne la cause précise de l’erreur.

Exemple
{
"message" : "Cet objet est déjà en cours de modification",
"errorType" : "ECRITURE_FORBIDDEN"
}