简体   繁体   中英

what is the correct way to create a REST endpoint with relationship

I want to create some endpoints to retrieve exceptions per country, startTime and endTime but i don't know what is the correct way to structure the endpoints, i have been talking with my co workers and we have different opinions about how to do it :

Option 1 Path params

  • /countries/{countryCode}/exceptions?startTime={value}&endTime={value} : To get all the exceptions per country in a certain timeframe

  • /countries/*/exceptions?startTime={value}&endTime={value} :To get all the exceptions in a certain timeframe

Option 2 Query params

  • /exceptions?country={countryCode}&startTime={value}&endTime={value} :To get all the exceptions per country in a certain timeframe

  • /exceptions?startTime={value}&endTime={value} :To get all the exceptions in a certain timeframe

Option 3 Path params in a different order

  • /exceptions/countries/{countryCode}?startTime={value}&endTime={value} :To get all the exceptions per country in a certain timeframe

  • /exceptions?startTime={value}&endTime={value} : To get all the exceptions in a certain timeframe

All the 3 options have pros and cons but we don't agree in which is the best practice. The question is what is the best option to create these endpoints.

If the exception needs a country to exist, that is, the exception is a sub resource of country , consider:

/countries/{countryCode}/exceptions?startTime={value}&endTime={value}

Otherwise you can manage the exceptions as a separate resource:

/exceptions?country={countryCode}&startTime={value}&endTime={value}

Path parameters should be used when you are displaying a hierarchy, eg to show all the comments that respond to the blog with id {id}, you would form this endpoint:

/blogs/{id}/comments

If you would want to filter these comments base on time, you would use query parameters for that:

/blogs/{id}/comments?start={start}&end={end}

In your case however, it seems, based on your question, that you have a large list with exceptions. This list can be filtered based on various aspects:

  • Country
  • Time

Since these properties are not part of the structural hierarchy (based on the context of your question), but simply properties giving more information about the exceptions, it would make sense to catch all them as query parameters to filter on, as such:

/exceptions?country={countryCode}&startTime={value}&endTime={value}

选项2其中Exception是一个单独的第一级实体,端点接受可选的国家/地区代码作为过滤属性,根据您的需求的有限描述最有意义。

It will be hard for you to choose which answer is correct, most answers seem to point out that your Option 2 is the right choice :)

As far as I'm concerned, what caused me the less troubles with REST architectures was to consider that every resource just have these forms, that return a list (possibly filtered) or a resource:

/mainResources
/mainResources/:id

And that /mainResources/:id/:relatedResources is an alias of /relatedResources?mainResourceId[]=... (returns a filtered list)

Your option 2 gives you the freedom to add more relations, such as /exceptions?country={countryCode}&anotherResource={anotherResourceId}&startTime={value}&endTime={value}

Your other options are not incompatible if you consider them as aliases.


Another reason I can think of to adopt URLs such as /mainResource/:id/subResource would be in the case of a denormalized relation such as:

{
   'attribute1': 'value1'
   'attribute2': 'value2'
   'attribute3': 'value3'
   'subResource': {
       'attribute4': 'value4',
       'attribute5': 'value5'
   }
}

then that kind of URL could return this sub-resource:

{
   'attribute4': 'value4',
   'attribute5': 'value5'
}

But that's just data filtering. And given your case, storing country exceptions this way wouldn't be convenient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM