Rest Standard: Path parameters or Request paramete

2020-01-27 02:40发布

问题:

I am creating a new REST service.

What is the standard for passing parameters to REST services. From different REST implementations in Java, you can configure parameters as part of the path or as request parameters. For example,

Path parameters http://www.rest.services.com/item/b

Request parameters http://www.rest.services.com/get?item=b

Does anyone know what the advantages/disadvantages for each method of passing parameters. It seems that passing the parameters as part of the path seems to coincide better with the notion of the REST protocol. That is, a single location signifies a unique response, correct?

回答1:

Paths tend to be cached, parameters tend to not be, as a general rule.

So...

GET /customers/bob

vs

GET /customers?name=bob

The first is more likely to be cached (assuming proper headers, etc.) whereas the latter is likely not to be cached.



回答2:

tl;dr: You might want both.


Item #42 exists:

GET /items/42
Accept: application/vnd.foo.item+json
--> 200 OK
{
    "id": 42,
    "bar": "baz"
}

GET /items?id=42
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
    {
        "id": 42,
        "bar": "baz"
    }
]

Item #99 doesn't exist:

GET /items/99
Accept: application/vnd.foo.item+json
--> 404 Not Found

GET /items?id=99
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
]

Explanations & comments

  1. /items/{id} returns an item while /items?id={id} returns an item-list.
  2. Even if there is only a single element in a filtered item-list, a list of a single element is still returned for consistency (as opposed to the element itself).
  3. It just so happens that id is a unique property. If we were to filter on other properties, this would still work in exactly the same way.
  4. Elements of a collection resource can only be named using unique properties (e.g. keys as a subresource of the collection) for obvious reasons (they're normal resources and URIs uniquely identify resources).
  5. If the element is not found when using a filter, the response is still OK and still contains a list (albeit empty). Just because we're requesting a filtered list containing an item that doesn't exist doesn't mean the list itself doesn't exist.

Because they're so different and independently useful, you might want both. The client will want to differentiate between all cases (e.g. whether the list is empty or the list itself doesn't exist, in which case you should return a 404 for /items?...).

Disclaimer: This approach is by no means "standard". It makes so much sense to me though that I felt like sharing.

PS: Naming the item collection "get" is a code smell; prefer "items" or similar.



回答3:

Your second example of "request parameters" is not correct because "get" is included as part of the path. GET is the request type, it should not be part of the path.

There are 4 main types of requests:

 GET
 PUT
 POST
 DELETE

GET requests should always be able to be completed without any information in the request body. Additionally, GET requests should be "safe", meaning that no significant data is modified by the request.

Besides the caching concern mentioned above, parameters in the URL path would tend to be required and/or expected because they are also part of your routing, whereas parameters passed in the query string are more variable and don't affect which part of your application the request is routed to. Although could potentially also pass a variable length set of parameters through the url:

GET somedomain.com/states/Virginia,California,Mississippi/

A good book to read as a primer on this topic is "Restful Web Services". Though I will warn you to be prepared to skim over some redundant information.



回答4:

I think it depends. One URL for one resource. If you want to receive that resource in a slightly different way, give it a query string. But for a value that would deliver a different resource, put it in the path.

So in your example, the variable's value is directly related to the resource being returned. So it makes more sense in the path.



回答5:

The first variation is a little cleaner, and allows you to reserve the request parameters for things like sort order and page, as in

http://www.rest.services.com/items/b?sort=ascending;page=6


回答6:

This is a great fundamental question. I've recently come to the conclusion to stay away from using path parameters. They lead to ambiguous resource resolution. The URL is a basically the 'method name' of a piece of code running somewhere on a server. I prefer not to mix variable names with method names. The name of your method is apparently 'customer' (which IMHO is a rotten name for a method but REST folks love this pattern). The parameter you're passing to this method is the name of the customer. A query parameter works well for that, and this resource and query-parameter value can even be cached if desired.

There is no physical IT customer resource. There is likely no file on disk under a customer folder that's named after the customer. This is a web-service that performs some kind of database transaction. The 'resource' is your service, not the customer.

This obsession over REST and web-verbs reminds me of the early days of Object Oriented programming where we attempted to cram our code into virtual representations of physical objects. Then we realized that objects are usually virtual concepts in a system. OO is still useful when done the right way. REST is also useful if you realize that RESTful resources are services, not objects.



标签: rest