quantumtremor
quantumtremor

Reputation: 3937

Creating one-to-one RESTful API relationship

I need to create a one-to-one relationship between a Game and a Site - each game happens in one site. In my database, site is an attribute of the Game object which points to a Site object.

I couldn't find much on the internet about this, these are my ideas:

GET /game/<game_id>/site

Gets a game's site, hiding the site id.

POST /game/<game_id>/site

Creates a game's site, this is only used once when creating the game.

PUT /game/<game_id>/site

Updates a game's site

DELETE /game/<game_id>/site

Deletes a game's site.

But what if someone wants to get a list of all the sites? Should I add a /sites URI and have the get method for the Site object detect whether a game_id has been passed in? Should I also let people access a site by /sites/<site_id> Or should I let the client populate their own list of sites by iterating over all games? Finally, I usually have an 'href' attribute for each object which is a link back to itself. If I went with the above design (incl. the /sites/ URI), do I link to /game/<game_id>/site or /sites/<site_id>? Should there be two places to access the same info?

Am I on the right track? Or is there a better way to model one-to-one relationships in REST?

If it matters, I'm using Flask-RESTful to make my APIs.

Upvotes: 6

Views: 4827

Answers (1)

eoinoc
eoinoc

Reputation: 3265

Your ideas make a lot of sense.

The big distinction is whether or not a site can exist independently of a game. It sounds like it can. For example, two games may point to the same site.

As far as I understand with RESTful API design, there isn't a problem with exposing the same site resource through both /game/<game_id>/site and through /sites/<side_id>. But REST encourages you to link data through hypermedia.

Exposing the site in two different places could complicate things, since you'd then expect to be able to interact with site objects through both of those URLs.

My recommendation to keep your structure explicit and simple would be:

Following the link object design, your game resource representation would include something like this:

{
  "game_id": 10,
  ...,
  "link": {
    rel: resource/site
    href: /api/sites/14
  }
}

Without more design work, this would mean you'll make a second call to get the site's information. Every design has its compromises :)

Upvotes: 2

Related Questions