Search code examples
restapi-designurl-design

How can I define my REST API?


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.


Solution

  • 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}