简体   繁体   中英

RESTful API design: list value options for query param

Let's say you are building an API returning a list of resources at

[GET] /resources
=> 
[
 {.. id: 1, foo: "A" ..}, {.. id: 2, foo: "B" ..}, {.. id: 3, foo: "A" ..}
]

Can be filtered using a query param :

[GET] /resources&foo=A
=>
[
 {.. id: 1, foo: "A" ..}, {.. id: 3, foo: "A" ..}
]

So far, so good.

Now you're asked to create an endpoint which returns the available values for foo ;
which endpoint would you expect to return the options available for filtering your resource?


My proposal is to use the HTTP method OPTIONS :

This method allows a client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action.

[OPTIONS] /resources
=> 
{
  foo: ["A","B"]
}

But I'm afraid this HTTP-method was designed for describing the connection itself, like HTTP verbs or CORS rather than describing the domain of your data.

Exactly, as you correctly state the OPTIONS method is reserved for communication options but not content and it is used for CORS verification.

I would use either one of these:

  • GET /resourceTypes?field=foo
  • GET /resource/types?field=foo

You can replace "types" with something more meaningful in your case, such as "allowedValues", "enum", etc...

Normally, in my experience, in REST the filterable values are known beforehand or you have a free search field with no predetermined values.

Your actual question targets how you can teach a client on what options are available for a certain resource. If you take a closer look at the Web and HTML in particular you might see that HTML uses Forms to teach browsers (=clients) on what the server expects as input from the client and also the choices it can take before sending a request.

The HTML spec contains the descriptions about the syntax and semantics of the respective elements you can use within a form. This way a server could send an option element to let a client chose between a couple or multiple options. Currently, there are a couple of drafts that attempt to translate this concept to other representation formats than HTML, but to my knowledge none of them is yet major enough or has gained widespread acceptance. Among these are some JSON based ones such as hal-forms , halform , ion and hydra .

According to Fielding

A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types)

application/json is not a very good representation format for true REST clients as it lacks the semantics to describe the respective elements a form-like representation may have and also the processing rules how a consumer of that representation should handle the information properly. Here one of the above mentioned media-types is for sure benefitial. The question shouldn't be which one to chose but how many you want to support. The more formats you support the more likely an arbitrary client will be able to interact with your system.

Clients and server should always use content-type negotiation to agree on a representation format both understand to exchange data. This reduces interoperbility concerns as both clients know how to process and interpret the agreed media type. In case no common representation format was available or the client sent a representation which is unfamiliar to the server, the server will inform the client about its inability to serve the client with content.

The whole purpose around REST is to allow servers to evolve freely in future without having to fear breaking clients. This is especially benefitial in areas with a lot of different clients and APIs that are not under your control. EDI would be such a domain to give you something to visualize better. Here lots of ERP systems and applications have to exchange business documents such as orders and invoices. There are a couple of standarized representation formats such as EDIFACT though there are plenty of custom formats in use which make the whole area quite interesting. You basically don't want to create a customized client (or server) for each ERP system you interact with but handle each message exchanged equally.

For front- to backend-communication though you don't really need a fully fleged REST architecture, as this probably puts more burden on you than it provides any good. The truth in REST is, that both, clients and servers, have to carefully be desinged to avoid coupling. If only one participant attempts to ignore one of the constraints Fielding put in place chances exist that a coupling remains which prevent servers from adding new capabilities in future without affecting clients or clients to stay able to interact with the services.

So, if you want to teach clients about what options they have on certain resources, take orientation on the Web and use media-types that are able to express that capability so clients can make use of it.

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