Is it RESTful to create a foreign key record from

2019-05-15 03:54发布

问题:

So I have some resources in my API with foreign key relationships and these fk records (by design) cannot be created unless a POST is made to that specific resource first.

I cannot create a Country by POSTing to Wine even though Country is a foreign key.

the POST is going to /api/wine not /api/country

In other words, if I send this payload to Wine resource:

{
  id: 79,
  name: "Bordeaux",
  country: {
      id: 76,
      code: "FR",
      name: "France"
    },
  year: "2005"
}

It will fail unless that country already exists. We cannot create the country from this POST because we are POSTing to the Wine resource and not Country.

This was by design because there are other foreign key relationships in the API that the consumer should never be able to modify or create. Furthermore, letting the consumer create multiple resources from a single payload seems like it would open up the possibility of introducing typo's, duplicate records, and dirtying the data, especially as the API scales and people are writing scripts around it and getting familiar with pushing data into it.

If I have a GET endpoint that reflects a chain of foreign key relationships

/api/planet/country/state/city/postal_code/

and I make a POST to:

/api/postal_code/

I should not be able to create a planet, country, state or city, I should only be able to refer to existing records for these resources if they exist and then finally create a new postal code.

My question is simply, what is the standard practice for this? Which methodology is more commonly used. If I were to open up my API to support creating every foreign key resource from a single endpoint - it seems like it would remove some of the benefits of using foreign key relationships in the first place.

回答1:

The way you have it is RESTful. To create a wine row, you do need to know all of the relevant details for that wine.

Nested routes are good when you have a use case to see all wine, versus wine just from a specific company.

Namely:

GET /api/wine/ <-- Would return all wine in the database vs.

GET /api/countries/76/wine <-- Would return all wine just for France.

Otherwise, both ways are RESTful in that the route describes the resource, and the patterns for updating it remain the same.



回答2:

Creating a parent resource when a new create child-resource api is called is not RESTful. If the parent-resource has to exist in order to create a child resource, the best way is to follow the hierarchical api structure and throw exceptions if the referred parent resource is not found.

Hierarchical API structure :
/api/countries/$country_id/wines - POST

If you follow this structure the api consumers will know that these parent resources must exist for the client apis to work properly.

On the other hand, if you feel that the api becomes lengthier, you can just throw exceptions when the parent resource(country) does not exist.