Reputation: 3322
I'm working on a REST API using Codeigniter and Phil Sturgeon's REST API Library.
https://github.com/philsturgeon/codeigniter-restserver
I've have the REST API working correctly, but now I'm wondering about modeling/REST for the relationships. For example, I have a many to many relationship between Contacts and Collections.
Format (excluding ?format=json)
GET
/rest_api/contact/{id}
GET
/rest_api/collection/{id}
Should the Relationships (m-m) be considered REST resources, such as?
GET (One)
/rest_api/contact_collection/{id}
GET (Collection/All)
/rest_api/contacts_collections/{contact_id}/{collection_id}
PUT (Save)
/rest_api/contact_collection/{contact_id}/{collection_id}
DELETE
/rest_api/contact_collection/{contact_id}/{collection_id}
Note, with Phil's CodeIngiter REST API, I don't think I can split it apart like:
PUT
/rest_api/contact/{contact_id}/collection/{collection_id}
I'm also questioning where/how the ID's should appear. Should the two ID's be part of the URL requested or be part of the PUT/POST data?
Upvotes: 0
Views: 1476
Reputation: 1
Thanks,
CodeIgniter-RestServer
♦♦♦Change Log
♦ Download Version 2.5: https://github.com/chriskacerguis/codeigniter-restserver/tree/v2.5
Upvotes: 0
Reputation: 10981
I would suggest modelling this as a collections
property of the contact
, to which you POST
IDs. i.e.
GET /collections/{id}
GET /contacts/{id}/collections
POST /contacts/{id}/collections
or better yet, instead of POST
, use LINK
and UNLINK
(https://datatracker.ietf.org/doc/html/draft-snell-link-method-01):
LINK /contacts/{id}
Link: </collections/{id}>;rel="collection"
(collection
is an IANA-defined relation: http://www.iana.org/assignments/link-relations)
Upvotes: 1
Reputation: 3322
Nicholas, I upvoted your answer. Here's what I've gone with so far. Let me know if you think I'm on the right path.
# URI's Explained for base "rest_api" (controller)
# collections resource
/collections/{id}
# contacts resource
/contacts/{id}
# collections contacts subresource
/collections/{collection_id}/contacts/{id}
Routed to
==> /contacts/id/{id}/collection_id/{collection_id}
In Restful-terms it helps a lot in not thinking of SQL and joins but more into collections, sub-collections and traversal.
Some examples:
# getting contact 3 who is in collection 1
# or simply checking whether contact 3 is in that collection (200 vs. 404)
GET /collections/1/contacts/3 ==> /contacts/id/3/collection_id/1
# getting contact 3 who is also in collection 3
GET /collections/3/contacts/3 ==> /contacts/id/3/collection_id/3
# adding contact 3 also to collection 2 (RELATIONSHIP)
PUT /collections/2/contacts/3 ==> /contacts/id/3/collection_id/2
# getting all collections of contact 3
GET /contacts/3/collections
# remove contact 3 from collection 1 (RELATIONSHIP)
DELETE /collections/1/contacts/3
# collection has a new contact, who is not yet added
POST /contacts
# from payload you get back the contacts insert id (44), now place contact in collection 1 (RELATIONSHIP)
PUT /collections/1/contacts/44
As you see I'm not using POST for placing contacts to collections but PUT, which handles the n:n relationship of contacts to collections.
PHP CodeIgniter Routes used are as follows. I'm really not sure if this is needed, but allows for the pretty URI's mentions above.
// Collections
$route['rest_api/collections/(:num)'] = "rest_api/collections/id/$1";
// Collection Contacts Subresource
$route['rest_api/collections/(:num)/contacts'] = "rest_api/contacts/collection_id/$1";
$route['rest_api/collections/(:num)/contacts/(:num)'] = "rest_api/contacts/id/$2/collection_id/$1";
Some of the rest_api controller methods get a little long, but it seems to work. I have to get the URI request params and the query string parmas, if used. Phil's CodeIgniter REST API had to be tweeked a bit to make sure to get the URI params when doing a PUT or DELETE request, as the values only existed in the $this->get() method; strange.
Upvotes: 0