Which REST API URI should be used for querying a relation to a single model object?

I am developing a REST API for a user management service (being used by other micro services). My model contains the types User and Server among others. Server to User relation is many-to-one (each user has a non-null foreign key to the server table).The Server type has a field named address.

I have to implement a REST endpoint which uses the user ID as input and returns the Server address as output (getting a more complex output is fine as long as it is not exaggerated).

My initial thoughts were to go for the following URI which returns the single Server object:

users/{id}/server

I looked for URI conventions but they seem to always refer to list of objects (see here for example):

users/{id}/servers

Which in my case would always return a list with a single Server object. Seems somewhat weird to me.

My main criteria for choosing the URI is keeping to mainstream conventions. I want the API to be as intuitive as it can be for the developers consuming it. Which endpoint should I use? Feel free to suggest other options.

2

In addition to @RobertHarvey ‘s answer.

If you are worried about dev’s job, then the choice should be flexible, rather than politically-correct.

Using /user/{id}/servers, we prepare the API for possible 0-N relationships. This approach brings some advantages over its alternative:

  • Working with empty arrays is easier than do it with nulls. (IMO)

  • Allows possible 0-N relationships

The las point lead us to the next advantage. One that matters.

If we change the API from a single response (/user/{id}/server) to multiple one (/user/{id}/servers), we will be forced to do versions of the API in order to grant backward compatibility.

Otherwise, the clients consuming the service may fail.

Thinking in further upgrades /user/{id}/servers is the one that brings more flexibility. Even when it only serves a single row.

Use the URI that makes sense for your particular application semantics.

If you want to return a single server object, the URI should be of the form:

users/{id}/server

If you might return multiple server objects in the future, and don’t want to have to add a new endpoint later, use the form

users/{id}/servers

If you really just want the address of a Server, and not an entire Server object, you could even do this:

users/{id}/serverAddress

My main criteria for choosing the URI is keeping to mainstream conventions. I want the API to be as intuitive as it can be for the developers consuming it.

The fact that this matters so much implies that your API may not actually be a RESTful one. With HATEOAS implemented, a client would read these links from another response served by your API without the need for a human being to ever read the URL (unless maybe analysing the logs). The example page you link to mentions that that the focus of your documentation in a REST API should be on the representations rather than endpoints.

So, what makes an API a good API? We will use the following tenets gathered from various authors across the web:

  • Has documention sufficient to guide the user of the API (and that does not redundantly document REST principles but instead focuses on representations, validation rules, security, etc.).
  • Requires knowledge only of a single URI entry point and access to documentation specifying the media types. (Note this is an hypermedia ‘stretch goal’.)

As far as REST is concerned, it simply doesn’t matter as all but a very low number of endpoints will have to be known to a programmer writing a client for your API. The rest should be free to change and don’t have to be human-readable at all. Whether or not they are legible is a matter of your preference and not a REST principle.

That said, you should pick whatever suits the semantics of your API.

Also, it’s highly unlikely that you actually need your API to be truly RESTful.

If you choose to provide a number of endpoints along with documentation for people to write programs hitting those endpoints, I suggest that you go with users/{id}/servers.

Why? It just seems more useful to me.

If your API is RESTful, it literally doesn’t matter. You’ll be free to change it from users/{id}/servers to /jabber{id}wocky and clients shouldn’t break as long as they understand the representations you’re returning and the representations contain the right links and enough metadata for the application client to understand what the link represents.

If your API is just a generic Web API serving data over HTTP without overriding the semantics of HTTP methods (let’s say, a Level 2 in Richardson’s Maturity Model), the URLs of the endpoints will matter more. I think users/{id}/servers just seems more robust. If you decide to make it possible for a user to have multiple servers assigned (whatever that means in your business domain), this should be easier to extend. If people start writing clients that expect users/{id}/server, it’s going to get weird if you actually introduce multiple servers per user. The semantics of this endpoint will have to change somehow (will it just be the first server? First based on what criteria?). Please mind that this is a wild guess on my part. It’s difficult to make this kind of decision without understanding the purpose of your API and the properties of those resources.

Furthermore, this choice may or may not matter much in terms of maintainability depending on how you approach API versioning. But that’s a very broad subject on its own.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *