Should I provide parent resource name in URL or no

2019-04-14 09:18发布

问题:

I am developing some basic restful web services using PHP and apache and I am wondering whether I should build the URLs providing the parent entity name or not. Let me explain this better:

I have 2 entities, lets suppose countries and cities. I am now just providing WS to get, create, update or delete cities but the API won't support countries manipulation via WS. I am remapping urls using mod_rewrite and I am providing the following urls in the api to manipulate cities:

. GET     /api/countries/<country_id>/cities            cities of country with id <country_id>

. GET     /api/countries/<country_id>/cities/<city_id>  city with id <city_id>

. POST    /api/countries/<country_id>/cities            add a city to country with id <country_id>

. PUT     /api/countries/<country_id>/cities/<city_id>  update the city whose country has id <country_id>

. DELETE  /api/countries/<country_id>/cities/<city_id>  delete city ...

I started looking careful at these urls and I got confused whether one should provide the parent entity name and id or not. I am making a great assumption and is that cities cannot be assigned to more than one country, i.e. it is not a many-to-many relationship. Assuming this I think a shorter URL pattern could be provided for many of the API functions. For example if the client wants to delete some city it would be enough if he send:

. DELETE /api/cities/14

I know that a city belongs to one country, and the client does not need to find out the country id before making the request.

The majority of the urls can be transformed into this shorter kind of url except for the first one (get all countrie's cities).

This is my first time developing web services and I haven't read too much about it so I may be probably misunderstanding something. Can I please get some advice? Thanks a lot and sorry for my rudimentary english.

EDIT1: I think the question can be generalized in 'How should I handle entities relationship in API urls?'

回答1:

'How should I handle entities relationship in API urls?' Don't. Instead use links in the resources you respond with.

For instance, if I do a GET on /cities/612 I might get back

{ 'city': 
  {
    'id': 612,
    'self': '/cities/612',
    'name': 'Sydney',
    'country': { 'name': 'Australia', 'href': '/country/61' },
    'region': { 'name': 'Asia Pacific', 'href': '/region/12' },
    'delete': {
      'method': 'delete',
      'href': '/cities/612'
    },
    'update': {
      'method': 'put',
      'href': '/cities/612',
        ...
    },
    ...
  }
}

This allows you to have any entity relationship you like, without having to worry about your URLs. You can alos easily add new relationships without breaking existing clients. For instance, if you wanted to add a new relationship of 'planet', GET on /cities/612 might now provide

{ 'city': 
  {
    'id': 612,
    'self': '/cities/612',
    'name': 'Sydney',
    'country': { 'name': 'Australia', 'href': '/country/61' },
    'region': { 'name': 'Asia Pacific', 'href': '/region/12' },
    'planet': { 'name': 'Earth', 'href': '/planet/1' },
    'delete': {
      'method': 'delete',
      'href': '/cities/612'
    },
    'update': {
      'method': 'put',
      'href': '/cities/612',
        ...
    },
    ...
  }
}

Have a look at A RESTful Hypermedia API in Three Easy Steps for more details.