IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[API REST] => Bonnes pratiques modélisation objet


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 065
    Par défaut [API REST] => Bonnes pratiques modélisation objet
    Bonjour @ tous,

    Je fait des échanges en API Restfull via Json, et ca fonctionne bien.
    j'ai un cas de figure un peu tordu, je sais y répondre, mais j'aimerais échanger pour voir si il n'existe pas une méthode plus standard.

    J'ai un objet "Projet" qui a des relation N/N avec "articles" (qui a un id, un nom et une quantité), on va dire.
    Pour le POST l'API me demande ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {  "id":2, "name": "toto", ...
      "articles": [
        { "id": 1, "length": 32 },
        { "id": 3, "length": 20 }
      ]
    }
    Aucun souci, c'est un tableau d'objets standards.
    Par contre, pour le GET, l'API me donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    { "id":2, "name": "toto", ...
      "articles": [{
    	"projectId": 2,
    	"articleId": 4,
    	"article": { "id": 4, "name": "Bonbon" },
    	"length": 20
      },
      {
    	"projectId": 2,
    	"articleId": 5,
    	"article": { "id": 5, "name": "Voiture" },
    	"length": 25
      }]
    }
    Et là, l'automatisme de DataContractJsonSerializer() est désarmé, même avec un IDataContractSurrogate.

    Ma façon de faire est de rajouter une propriété "article" dans mon objet "article" (avec l'attribut "DataMember", bien sur).
    Et lors du OnDeserialized() du projet, je copie les valeur de la propriété "article" dans les propriétés de ce même objet ad hoc.
    Ça fonctionne, mais je ne trouve pas ça très générique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            [OnDeserialized()]
            internal void OnDeserializedMethod(StreamingContext context) {
                foreach (var item in articles) {
                    if (item.article!=null) {
                        item.id = item.article.id;
                        item.name = item.article.name;
                    }
                }
            }
    Qu'en pensez vous ?

    Merci d'avance de vos lumières.

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut
    Personnellement, je n'aime pas utiliser la sérialisation json <-> classes.
    Je préfère m'en tenir au parser qui retourne un object étant un : null, int, double, string, boolean, List<object>, Dictionary<string, object>.

    Ensuite, avec le type de requête je connais le type d'objet parent que je vais recevoir, donc j'appelle un constructeur de cet objet avec le Dictionary<string, object> reçu.
    (ou je crée une liste du type d'objet que je vais recevoir).

    Dans ton cas, je n'ai qu'à vérifier simplement l’existence de champs dans le Dictionary<string, object>
    (ou alors je passe un booléen, ou alors j'utilise un autre type d'objet (qui implémente une interface simillaire ou qui étendent de la même base, ou complètement indépendants) : tout dépend du contexte).

    __

    Edit:

    Chaque objet doit savoir se reconstruire en JSON de plusieurs manière possibles, aussi.
    Justement pour que ce soit plus rapide (admettons une liste d'id)

    __

    Edit :

    Pour la sérialisation, avec l'outil que tu utilises, tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [DataMember(Name = "article", IsRequired = false)]
    Pour la désérialisation, je ne sais pas.. une interface ? (je ne sais pas si c'est possible)

  3. #3
    Rédacteur/Modérateur
    Avatar de beekeep
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 2 005
    Par défaut
    Bonjour,

    le package le plus utilisé est celui de Newtonsoft:
    http://www.newtonsoft.com/json

    Pas de problème pour sérialiser ou désérialiser les objets imbriqués avec des listes.

    Mais théoriquement une API REST ne renvoi pas des objets imbriqués mais fourni un chemin par ressource. (le projet et les articles correspondants sont récupérés en deux requêtes distinctes)

  4. #4
    Membre éprouvé Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 065
    Par défaut
    Bonjour à vous deux, merci pour vos infos.

    Oui, j'ai eu l'occasion d'utiliser cette API dans mon projet.
    Donc en fait l'idée générale est de prendre un composant qui prend le tout venant Json et le caste en dynamic.
    Et après, dans une méthode de chaque model, il y a un espèce de mapping. Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                    dynamic js = Newtonsoft.Json.Linq.JObject.Parse(MonJsonStr); // JSON to LINQ. http://www.newtonsoft.com/json
                    if ((js.result is object) && (js.result.address_components is IEnumerable<object>)) {
                        if (js.result.address_components.Count > 0)
                            locality = js.result.address_components[1].long_name;
                        if (js.result.address_components.Count > 1)
                            region = js.result.address_components[2].long_name;
                        ret = true;
                    }
    Il est vrai que ça évite d'avoir des propriétés juste pour la communication, mais je trouve que c'est très verbeux (donc maintenance difficile) et j'ai des doutes sur l'optimisation en terme de performances...
    Mais c'est une solution, et après c'est à chacun de faire son choix.

    Sinon, j'aime bien l'idée d'avoir une API getAll() qui ne renvoie le nécessaire pour remplir les tableaux et un Get(id) qui me renvoie tout même les tables de relations.
    En tout cas, c'est que mon API fait... Après, s'il faut charger toutes les relations une à une, pourquoi pas, mais ca fait gérer les exceptions en cas de souci en chemin.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 18
    Dernier message: 03/09/2019, 01h02
  2. Réponses: 1
    Dernier message: 23/09/2010, 14h38
  3. Réponses: 13
    Dernier message: 07/04/2010, 20h22
  4. Bonnes pratique : ne rien retourner ou retourner un objet ?
    Par harf18 dans le forum Général Java
    Réponses: 10
    Dernier message: 12/03/2010, 12h32
  5. [Article] Bonnes pratiques objet en .net : Introduction aux principes SOLID
    Par Philippe Vialatte dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 25/02/2009, 17h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo