Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple optional query string parameters REST API GET

I am using web api 2 to implement a restful service. After doing some research on best practices everyone seems like they are having different opinions on how to do the following. I have a GET

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

This GET method returns a list. There are multiple ways of getting the data from this method.

  • Get by crewId only
  • Get by shiftDate only
  • or
  • Get by crewId and shiftDate
  • Do you (1) Mark the crewId and shiftDate as optional?

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

    and then have bunch of if statements to check what is filled and what is not filled to be able to do 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
    }
    

    To me this looks crazy to do especially if you have many parameters you would have too many "if" statements in your code.

    Do you (2) Have different set of gets?

    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)
    

    and then you would have your URI Route map to the method

  • .../api/GetByCrewId?crewId=1234
  • .../api/GetByShiftDate?shiftDate=1111-11-11
  • .../api/GetByCrewIdShiftDate?crewId=1234&shiftDate=1111-11-11
  • is option 2 restful?

    Or is there an better options (3).

    Both options above will work just making sure I am using best practices and following REST standards. Just seems like I am missing something and hopefully you can put me in the right direction.

    like image 798
    Nick Manojlovic Avatar asked Jan 19 '16 16:01

    Nick Manojlovic


    People also ask

    How do I pass multiple parameters in GET request?

    Multiple parameters can be passed through the URL by separating them with multiple "&".

    How do I pass multiple query parameters in REST URL?

    Query parameters are passed after the URL string by appending a question mark followed by the parameter name , then equal to (“=”) sign and then the parameter value. Multiple parameters are separated by “&” symbol.

    How do I send optional parameters in REST API?

    We can make a route parameter optional by adding “?” to it. The only gimmick is while declaring a route parameter as optional, we must specify a consequent default value for it: [HttpGet("GetById/{id?}")]

    Can we send parameters in GET request in REST API?

    REST API endpoints can pass data within their requests through 4 types of parameters: Header, Path, Query String, or in the Request Body.


    2 Answers

    You don't want option (2) - to be RESTful you want nouns in your URL.

    So you want your URL's to look like:

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

    (I can't work out what your Items are, based on the 'Crew' and 'Shift' parameter names. What has a Crew and a Shift date?? Fishing trips?? If so, the url would be better as /api/fishing-trips/?crewId=....&shiftDate=...

    As for the controller, I'd go for something like:

    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));
    }
    
    like image 118
    Anthony Avatar answered Sep 19 '22 05:09

    Anthony


    Reviewing Best Practices: Understanding REST Headers and Parameters it states that the use of the query parameter would indicate that it is optional. If you can make a single value required and the others optional it might help clarify the URI.

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

    In the end if your items are all optional then use of the "?" is probably the best route. Further information on types of parameters are available at RFC 6570.

    Note that your choice may have impact on any queueing that you choose to use and the path-style parameter expansion may make the most sense. More information also at Understanding REST Parameters.

    Lastly you may wish to create these as search parameters then, if you find that your users are often requesting the same search, you can package it into a single REST path.

    For example,

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

    You could also provide a simplification along with optional parameters, for example,

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

    These last examples are subjective from my research but more information is available at Best Practices for a Pragmatic Rest API and RESTful URL design for search.

    like image 28
    McArthey Avatar answered Sep 18 '22 05:09

    McArthey