web-dev-qa-db-fra.com

Plusieurs paramètres de chaîne de requête facultatifs REST API GET

J'utilise Web api 2 pour mettre en place un service reposant. Après avoir effectué des recherches sur les meilleures pratiques, tout le monde semble avoir des opinions divergentes sur la manière de procéder. J'ai un GET 

public HttpResponseMessage Get(string crewId, string shiftDate, int offset = 1, int limit = 10)

Cette méthode GET renvoie une liste. Il existe plusieurs façons d'obtenir les données de cette méthode. 

  • Obtenir par crewId seulement
  • Get by shiftDate uniquement
  • ou
  • Obtenir par crewId et shiftDate
  • Est-ce que vous (1) marquez crewId et shiftDate comme facultatif? 

    public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10)
    

    et puis avoir un tas de si déclarations pour vérifier ce qui est rempli et ce qui n'est pas rempli pour pouvoir faire des actions

    if(crewId != null && shiftDate == null){
      // Get by crewId
    }else if(crewId == null && shiftDate != null){
      // Get By shiftDate
    }else if(crewId != null && shiftDate != null){
      // Get By crewId and shiftDate
    }
    

    Cela me semble fou, surtout si vous avez beaucoup de paramètres, vous auriez trop d’énoncés "if" dans votre code.

    Avez-vous (2) un ensemble différent d’objectifs?

    public HttpResponseMessage GetByCrewId(string crewId, int offset = 1, int limit = 10)
    public HttpResponseMessage GetByShiftDate(string shiftDate, int offset = 1, int limit = 10)
    public HttpResponseMessage GetByCrewIdShiftDate(string crewId, string shiftDate, int offset = 1, int limit = 10)
    

    et puis vous auriez votre carte URI Route à la méthode 

  • .../api/GetByCrewId? crewId = 1234
  • .../api/GetByShiftDate? shiftDate = 1111-11-11
  • .../api/GetByCrewIdShiftDate? crewId = 1234 & shiftDate = 1111-11-11
  • l'option 2 est-elle reposante?

    Ou existe-t-il de meilleures options (3).

    Les deux options ci-dessus fonctionnent uniquement en m'assurant d'utiliser les meilleures pratiques et de respecter les normes REST. Il me semble que quelque chose me manque et j'espère que vous pourrez me mettre dans la bonne direction.

    7
    Nick Manojlovic

    Vous ne voulez pas l'option (2) - pour être RESTeux, vous voulez des noms dans votre URL.

    Donc, vous voulez que votre URL ressemble à ceci:

    /api/items/?crewId=1234&shiftDate=1111-11-11
    

    (Je ne peux pas déterminer quels sont vos éléments, en fonction des noms de paramètres 'Crew' et 'Shift'. Qu'est-ce qui a une date d'équipage et une date de décalage? Voyages de pêche ?? Si oui, l'URL serait meilleure comme/api/sorties-de-pêche /? crewId = .... & shiftDate = ...

    En ce qui concerne le contrôleur, je choisirais quelque chose comme:

    public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10) {
    
        return dataSource.Where(x=> (x.CrewId == crewId || crewId == null)
                && (x.ShiftDate == shiftDate || shiftDate == null));
    }
    
    5
    Anthony

    Révision Meilleures pratiques: comprendre les en-têtes et les paramètres REST il indique que l'utilisation du paramètre de requête indiquerait qu'il est facultatif. Si vous pouvez rendre une seule valeur requise et les autres facultatives, cela peut aider à clarifier l'URI.

    /api/fishing-trips/crew/{crewid}?shiftdate=1111-11-11
    

    En fin de compte, si vos éléments sont tous facultatifs, utilisez le "?" est probablement le meilleur itinéraire. De plus amples informations sur les types de paramètres sont disponibles sur RFC 6570

    Notez que votre choix peut avoir un impact sur la mise en file d'attente que vous choisissez d'utiliser et le développement des paramètres de type chemin peut s'avérer plus judicieux. Plus d’informations sur Comprendre REST Paramètres .

    Enfin, vous pouvez créer ces paramètres en tant que paramètres de recherche. Si vous constatez que vos utilisateurs demandent souvent la même recherche, vous pouvez la regrouper dans un seul chemin REST.

    Par exemple,

    /api/fishing-trips/search?crew=1234
    /api/fishing-trips/search?shiftDate=1111-11-11
    /api/fishing-trips/search?crew=1234&shiftDate=1111-11-11
    

    Vous pouvez également fournir une simplification avec des paramètres facultatifs, par exemple,

    /api/fishing-trips/today
    /api/fishing-trips/today?crew=1234
    /api/fishing-trips/crew/1234/today
    

    Ces derniers exemples sont subjectifs, mais plus d’informations sont disponibles sur Meilleures pratiques pour une API repos pragmatique et Conception d’une URL RESTful pour la recherche .

    2
    McArthey

    J'ai déjà fait quelque chose comme ça avant. Puisque vous pouvez utiliser l'un ou l'autre ou les deux, j'utiliserais les paramètres facultatifs:

    public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10)
    

    Puis construisez votre requête. Par exemple, quelque chose comme ceci:

    var query = "";
    if (!String.IsNullOrEmpty(crewId)) {
      query += $"crewId='{crewId}'";
    }
    if (!String.IsNullOrEmpty(shiftDate)) {
      if (query.Length > 0) query += " AND ";
      query += $"shiftDate='{shiftDate}'";
    }
    if (query.Length == 0) {
      //neither crewId or shiftDate were given
      //return some kind of error
    }
    
    2
    Gabriel Luci

    Etant donné que je suis sur le point de l'implémenter moi-même, je dirai qu'il devrait s'agir d'une action de méthode GET avec plusieurs paramètres facultatifs. 

    Pourquoi? Parce que vous ne devriez pas vous inquiéter de cette logique de requête dans la couche API REST. Après tout, vous créez effectivement une clause de discrimination AND avec plusieurs paramètres (à savoir CrewId = 1 AND ShiftDate = 2016-01-01). Et si vous ne fournissez pas de paramètres, renvoyez tous les éléments.

    Je vais passer mes paramètres tout au long d'une procédure stockée SQL qui a des valeurs par défaut spécifiées et renverra les résultats en fonction des paramètres passés.

    N'oubliez pas que, de nombreuses manières, les méthodes REST sont directement mappées sur CRUD. Traitez donc votre API comme telle: REST API Tutorial

    1
    toadflakz