I assume you are expecting your site have a large amount of traffic. If that assumption is correct, I would say go with a tweaked version of Implementation 3.
If api.site.com and gateway.site.com are on two different servers, I would also have a third server to house the DB and have both apps leverage the centralized DB. This will eliminate the need for api.site.com and gateway.site.com to even know about each other and keep all work in a designated area, making any debugging that much easier.
And if my assumption is incorrect, I'd say go a differently tweaked version of Implementation 3. So you'd build you two separate apps that communicate with the same Db, and simply house everything on the same server. Which is basically what I just said above but all on the same server. This should reduce initial overhead and make scaling a breeze when the time comes.
POST is the "append" verb, and also the "processing" verb. PUT is the "create/update" verb (for known identifiers), and almost looks like the right choice here, because the full target URI is known. projectId
and siteId
already exist, so you don't need to "POST to a collection" to produce a new ID.
The problem with PUT is that it requires the body be the representation of the resource you're PUTting. But the intent here is to append to the "project/sites" collection resource, rather than updating the Site resource.
What if someone PUTs a full JSON representation of an existing Site? Should you update the collection and update the object? You could support that, but it sounds like that's not the intent. As you said,
the only data I really need are ProjectId and SiteId
Rather, I'd try POSTing the siteId
to the collection, and rely on the "append" and "process" nature of POST:
POST myapi/projects/{projectId}/sites
{'id': '...' }
Since you're modifying the sites collection resource and not the Site resource, that's the URI you want. POST can know to "append/process" and add the element with that id to the project's sites collection.
That still leaves the door open to creating brand new sites for the project by fleshing out the JSON and omitting the id. "No id" == "create from scratch". But if the collection URI gets an id and nothing else, it's pretty clear what needs to happen.
Interesting question. :)
Best Answer
If you google "REST partial update" you will get a lot of opinions.
Having said that I'll give you my thoughts.
A PUT should be used for a full update of a resource so only changing one parameter you are better off PUTting to /purchase_order/1 a recent result of a GET to /purchase_order/1 with the status field changed from draft to sent.
Depending on the semanics of your system you might consider a draft and a sent item to be different resources (with different primary keys) and so a GET to /purchase_order/1, change the status, then POST to /purchase_order/ (although I'm guessing that in this case purchase orders don't become new purchase orders when thir status changes).
Another option would be to send a PUT to /purchase_order/1/status with a value of sent, this could then be interpreted on the server side as an update to the sub resource status of the resource purchase_order. You could even return 303 pointing back at the /purchase_order/1 resource to let the client know that a different resource than they interacted with has changed and where to find that resource.
You could consider the PATCH verb but if you follow the semantics properly then you shouldn't just send the requested state, but rather a content-type that you specify that lists a set of operations you wish to be applied.
If an action is going to have side effects then you need to make this clear in your API. So be careful when using PUT, which is designed to be idempotent.