4

I'm working on a Spring Boot REST API that handles document and can launch a check on a document.

I have a document resource: /doc:

  1. Create a doc with POST /doc
  2. Rest of the CRUD actions with /doc/{id}

Now I can launch a check on a doc, check can be seen either as an action or as a sub-resource.

It's pretty straightforward to launch (create) a check on a document: POST /doc/{id}/check

The check can however take some time so I want to give the user the choice to launch a synchronous or asynchronous check.

How would I handle this path wise?

  1. Should the user choose sync or async check through a query parameter on POST /doc/{id}/check?
  2. Should I create 2 separate paths?

Also in the case of an async check, I would create a temporary Task resource that can be pooled to know the status of the check.

But then if both check and task are returned from the same path it gets confusing, no?

I read an article that says the resource returned in async should be a check resource filled as much as possible but with a link to the task that can be pooled.

That seems like a good way; I would return a partial check if async with a link to the /task/{id} associated with the check.

However I'm still confused as to what path my API should offer to let the user pick between sync and async checks.

How would you handle it path and resource wise?

DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
TheBakker
  • 2,852
  • 2
  • 28
  • 49

2 Answers2

2

Basically it's up to you. Usually if it's a big chunk of data you want to query like /resource/{id} most APIs I have used use GET for synchronous requests and POST for async request returning task or job ID.

For POST in your case if the creation/checking takes time I would consider always doing it asynchronous and returning HTTP 202 Accepted and doc/{id}/check/{id} url where the user can see the result if it is ready or some status that it is still working.

If you want to give them a choice to wait or not it's up to you how to do it. There is a standard header that can be used to modify behavior. For example Expect: 202-accepted for async calls and no header or Expect: 201-created for synchronous calls. This makes the API a bit less clear even though it is a standard. Most people (including me) would probably stick to adding a parameter to the URL for clarification. I don't think it should be in the POST data because it should be data related to the object you are creating

Veselin Davidov
  • 7,031
  • 1
  • 15
  • 23
  • Thanks for your answer, I can't do it only asynchronously, I've to offer both, it's mandatory for the customer. Also requring user to add the header might be a bit over the top, readability wise for my customers. – TheBakker Apr 12 '18 at 08:26
  • @TheBakker, Did you manage to support both? – Karthik Sep 04 '21 at 05:45
  • Well I went with 2 separate past, trying to make it so the sync method is the one with the not standard sub resource path, but not too happy ... Was mostly wondering about feedback from people confronted with the same question, as I guess there are no "right" answer on this – TheBakker Sep 05 '21 at 08:03
0

There are multiple questions here. I would try to answer one by one

Checking the health of a resource can be done with query param

/doc/{id} - GET Get the resource details
/doc/{id}?healthCheck=true&async=true GET - Get the resource details and trigger an async health check

For the async health check the response as you mentioned will be 202 and the response contains the link to the health status URL

HTTP/1.1 202 Accepted
Location: /doc/12345/status

If the client sends a GET request to this endpoint, the response should contain the current status of the request. Optionally, it could also include an estimated time to completion or a link to cancel the operation.

Reference https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design

asolanki
  • 1,333
  • 11
  • 18
  • Thanks for your answer. What bother me is with the healthCheck query parameter you change the type of resource that is returned. Is that something standard ? – TheBakker Apr 12 '18 at 09:04
  • 1
    I have not seen any defined rule. The examples that I have seen use a different resource. It all depends on the type of resource and corresponding status. See the option 1 in accepted answer below. https://stackoverflow.com/questions/33009721/long-running-rest-api-with-queues – asolanki Apr 12 '18 at 10:43
  • Interesting read. Although I'm still stuck with my 2 way of doing one thing issue as far as past go. I've already implemented the Task notion for async though – TheBakker Apr 12 '18 at 13:20