api-guidelines icon indicating copy to clipboard operation
api-guidelines copied to clipboard

Reference implementation REST API

Open istibekesi opened this issue 2 years ago • 5 comments

Question: Is there any reference implementation of the Microsoft REST API Guidelines publicly available?

(I’ve checked the GitHub API, but I’ve noticed slight differences. For example, GitHub uses PUT, for submit a command, instead of POST)

istibekesi avatar Jun 16 '23 09:06 istibekesi

The older guidelines were implemented haphazardly and are still used for M365 services.

However, we actively work on and update the Azure REST guidelines:

  • Azure services that have already shipped will continue to work as is (and not follow these guidelines) because we do not want to break customers.

  • When an existing Azure service introduces new features, they follow their exiting patterns to be consistent within the service.

    • However, if the old pattern had problems, then they will not follow the problematic pattern and will adopt the newer guidelines.
  • New/Greenfield Azure services adopt the latest guidelines.

A newer service to look at is Azure Communication Service (ACS). There are several other newer services as well.

JeffreyRichter avatar Jun 16 '23 15:06 JeffreyRichter

I’ve checked the Azure Guidelines and compared them to one of the ACS service references you recommended to look at.

A few questions came to my mind that could help me see if I understood the guidelines correctly.

  • POST {endpoint}/chat/threads
    • Does the same JSON schema for POST request/response not apply to this endpoint?
    • How do I identify field field mutability in this endpoint? Is 'participants' an update field? Is 'invalidParticipants' a read field?
    • Are 'participants.rawId' and 'communicationUser.id' the same? What is the purpose of having both?
  • POST {endpoint}/chat/threads/{chatThreadId}/participants/:add It seems to be an action, so shouldn't it return 200 instead of 201? Why having / between the resource and the action? /participants/:add vs /participants:add?
  • POST {endpoint}/chat/threads/{chatThreadId}/participants/:remove It seems to be an action too, so shouldn't it return 200 instead of 204?
  • POST {endpoint}/chat/threads/{chatThreadId}/readReceipts It creates a new resource, shouldn't it return 201 along with a location header?
  • Is there any reason behind placing create, delete, and list under the "Chat" group and read, update under the "Chat thread" group for chat CRUDL in the docs?

istibekesi avatar Jun 23 '23 00:06 istibekesi

  • POST can be used for resource creation (although we strongly discourage this and strongly prefer PATCH instead). When used for resource creation, the request & response bodies should be the same.

    • You can indicate in JSON schema which fields are read-only and which are not
  • POST can also be used for RPC-like actions (not resource creation) and in this case, the request & response are always different like how a method's inputs and outputs are completely different.

    • In this case, it doesn't make sense to mark any fields as read-only because the input & output schemas are completely different.
  • Are 'participants.rawId' and 'communicationUser.id' the same? What is the purpose of having both? [JR] I'm not an ACS expert. As this is a domain-specific question, you need to ask them. It is definitely our hope that teams use great names consistently when designing their API contract - I hope that was done here too.

  • POST-actions should return 200; not 201. If this returns 201, that is probably a bug.

  • At one point our guidelines said to use "/:". We have since removed the last "/" but ACS is grandfathered in as using the "/". If we were starting ACS from scratch today, it would be "/participants: add" (no slash before colon.

  • About "/:remove": Yes, 200 is preferred over 204 as it is not breaking to return 200 with a {} JSON body that can add fields in the future. Returning 204 with no body today and changing this to 200 with a body tomorrow can be breaking for some SDK languages and for clients specifically looking for 204 today will not see 200 tomorrow. This may also be a bug and 200 should be returned but it is breaking to fix that now. Hopefully, the operation will NEVER have something to return.

  • About "/readReceipts": 201 is OK and clients MUST also treat 200 as OK as the POST operation can be retried and this is why repeatability headers are required for POST-resource-create operations. Yet more reasons why we don't like POST for resource creation. The response can (and should) have the newly-created (read-only) resource id as a field and this is enough for the client to construct the full URL to the new resource. A Location header is not required.

  • You'd have to ask the ACS team as it is domain specific. I suspect that they expect their customers to find the things they are looking for more easily.

JeffreyRichter avatar Jun 23 '23 18:06 JeffreyRichter

It's a really interesting conversation. If I may ask as well, can you mention an example where PATCH is used for resource creation? The examples I skimmed just didn't.

rszabolcs avatar Jul 11 '23 07:07 rszabolcs

Here's an example, see https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/agrifood/data-plane/Microsoft.AgFoodPlatform/preview/2023-06-01-preview/agfood.json

Some of these resources have PATCH (without any PUT) and the docs for PATCH says: "Creates or updates an application data resource under a particular party." (for example).

JeffreyRichter avatar Jul 12 '23 21:07 JeffreyRichter