Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTful API design - how to handle foreign keys?

Tags:

rest

I'm designing a RESTful API and I'm trying to figure out how to show and update foreign keys for resources.

Let's I have an object User and it has an id, name and a foreign key (many-to-one relation) to entity: Computer.

What I see in most of the examples online:

GET /users/1

{
  id: 1,
  name: "Bob",  
  computer: "<url>/computers/5"
}

Which I can understand, it's a link to another resource. But what do you do when you want to pick another computer for bob?

PUT /users/1

{
  name: "Bob",
  computer: "<url>/computers/4"
}

This feels really weird. I'm also thinking about the following case: Say the person that has to implement the API can choose a computer for Bob using a dropdown and the current one should be selected, I'd need the id to do that. Do I have to parse the url myself to chop off the id?

Is there a reason why I should not just do:

GET /users/1

{
  id: 1,
  name: "Bob",  
  computerId: 5
}

PUT /users/1

{
  name: "Bob",
  computerId: 4
}
like image 876
Geoffrey De Vylder Avatar asked Nov 26 '15 12:11

Geoffrey De Vylder


People also ask

How do REST API communicate with each other?

REST allows applications to communicate with each other by carrying JSON data between the client and server.


1 Answers

I would be tempted to formalise the HATEOAS a little here and have:

GET /users/1

{
  links: [
    { rel: "computer", href: "/users/1/computers/5" },
  ],
  user: {
    id: 1,
    name: "Bob",
    computer: 5,
  }
}

PUT /users/1

{
  name: "Bob",
  computer: 4,
}

GET /users/1

{
  links: [
    { rel: "computer", href: "/users/1/computers/4" },
  ],
  user: {
    id: 1,
    name: "Bob",
    computer: 4,
  }
}

The link URLs can obviously be /computers/n if that's your preference.

This allows your representations to consistently be just data, AND the body of GETs to supply the URLs that your application can use. This way, if you change your URL hierarchy (i.e from /computers/n to /users/m/computers/n) you do not need to change any client code that manually constructs URLs.

like image 120
Mark Gibson Avatar answered Sep 17 '22 19:09

Mark Gibson