0

I have 3 models: tournament, championship and competitor:

  • A tournament has many championships;
  • A championship belongs to tournament;
  • A championship has many competitors.

So, to list all the competitors from all the championships, the URL is:

GET https://base.com/tournament/{slug}/competitors

but to add a competitor, it is related to championship so:

POST  https://base.com/championships/{id}/competitors

Is it ok that for the same model, two verbs (GET and POST) has differents URI? Otherwise, how should I do?

I fell like doing:

POST  https://base.com/tournaments/{slug}/championships/{id}/competitors 

has a no necessary field.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
Juliatzin
  • 18,455
  • 40
  • 166
  • 325

2 Answers2

2

Is it ok that for the same model, two verbs (GET and POST) has differents URI?

This is likely to cause confusion for the API consumers, so I advise you use the same URI.


Bear in mind that the REST architectural style, described in the chapter 5 of Roy T. Fielding's dissertation, defines a set of constraints for applications build on the top of such architecture. But it says nothing about what the URIs must be like.

The examples shown in a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URI structure that looks friendly and easy to read. While it may be desirable, it's not mandatory for REST applications.


There are plenty of valid approaches you could go for. If a competitor requires a championship to exist and a championship requires a tournament to exist, you could express such hierarchy using:

/tournaments/{slug}
/tournaments/{slug}/championships/{id}
/tournaments/{slug}/championships/{id}/competitors/{id}

But the last URI may be considered too long and may be hard to remember. So you could simply split it, then you don't need to send many parameters around:

/tournaments/{slug}
/championships/{id}
/competitors/{id}

If you need to perform any filtering, you could use query parameters. For example:

/championships/{id}?tournament={slug}
Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • Ok, nice answer. But so, what would you recommand ? what is for you the best trade off ? inconsistency in URIs, or easy to read URL ? – Juliatzin Jun 19 '18 at 09:33
  • @JuliatzindelToro Both approaches are fine to identify your resources and the choice boils down to a _personal preference_. I would probably go for the approach with short URIs (but that's just a personal preference). – cassiomolin Jun 19 '18 at 09:49
  • 1
    There is no need to actually have to remember any URI except for the initial (or bookmarked) one as servers should provide any URI a client can invoke from the current "state" the client has previously fetched. IMO the link relation name is way more important than any URI structure. We (humans) also like to have links that describe the content of the page rather than having to parse the link for any valuable information. The same holds true for applications following a REST architecture style. – Roman Vottner Jun 19 '18 at 13:45
0

Reminder: REST doesn't care what spelling you use for your URI

Is it ok that for the same model, two verbs (GET and POST) has differents URI? Otherwise, how should I do?

It's OK, but there are certain costs associated with it.

Let's review what Fielding had to say (2008)

REST is intended for long-lived network-based applications that span multiple organizations. The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.

One of the replication styles that Fielding identifies in his thesis is the cache; he goes on to add that style to his definition of REST

In order to improve network efficiency, we add cache constraints to form the client-cache-stateless-server style.... Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.

In HTTP, the semantics of caching are defined in RFC 7234; Section 4.4 describes invalidation.

A cache MUST invalidate the effective Request URI (Section 5.5 of [RFC7230]) as well as the URI(s) in the Location and Content-Location response header fields (if present) when a non-error status code is received in response to an unsafe request method.

This means that communication passing through generic clients, that know nothing of the specifics of your protocols, can invalidate their local copy of stale representations, based on the metadata in the request and response.

(This was a bigger deal in the past, when we weren't encrypting all of the traffic; but it still applies to (a) the client's local cache and (b) the caching reverse proxy sitting in front of the domain model).

As far as REST is concerned, URI are opaque; there's no fundamental relationship between

/A
/A/B
/A/B/C
/A/B/D
/A/E

So if the caches see that /A/B should be invalidated, they can do that, but they won't do anything with the other URI.

For PUT, DELETE, PATCH -- the semantics of these methods is very specific to the effective request URI.

If you apply that same approach to POST, then you get cache invalidation "for free".

Walking through a simple example; imagine a web site, where we have

GET /superCoolResource
GET /superCoolResource/editForm

We want to induce some change in /superCoolResource, so we load the edit form, and submit it....

POST ...?

If we POST to /superCoolResource/editForm, then we are telling the client that the cached copy of the form should be reloaded if the POST is successful. But that probably isn't what we want -- it's more likely that the form stays the same, and the /superCoolResource is the thing that changes. That means we probably want to make /superCoolResource the target URI

GET /superCoolResource/editForm

200 OK

... <form action="/superCoolResource" method="POST"> ....

and magically the client's cache, the origin server's cache, and any intermediate caches that are privy to the conversation know to evict their old copy of /superCoolResource when the POST succeeds.

Community
  • 1
  • 1
VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91