How do I implement dry run option to a REST api so I have a way of knowing it is implemented?
Asked Answered
M

1

7

In my system, I have multiple services exposing REST apis for their resources. A specific service on the system needs to make rest calls to other services in dry-run mode in specific circumstances just to do validation. Even though the body of the request has meaningful payload for the api, nothing will be persisted, no states will be changed and no messages will be sent. The tricky part is that if this service calls a REST api which didn't implement dry-run mode, it will modify the resource instead of just validating. I need a way to make dry-run requests only if the receiving service implemented dry-run in its api, otherwise the request must fail.

I had these ideas so far:

Passing a query parameter

I could pass a flag as a query parameter but the request still goes through if the api doesn't know of the parameter.

POST /resource?dry-run=true

Passing a flag in header

Similar to query parameter, unknown header fields are ignored.

Exposing a dry-run api just for validating

This solution works as I can verify dry-run version of the URL exists or not but I don't want to expose more endpoints just for validation

POST /resource
POST /resource/dry-run

PUT /resource/{id}
PUT /resource/{id}/dry-run

Inject the flag to the body of resource

This looks to be a solution but when the api doesn't support this field, JSON serialization will fail. In that case, I can't tell whether it is because dry-run is not supported by the api or there is actually a problem in the body. Also, it doesn't feel right since dry-run is not a part of the resource.

POST /resource

{
  "dry-run":true,
  ...
  ...
}

Is there a better way to implement a dry-run feature to REST api where the request will fail if the service have not implemented it?

Mouse answered 16/8, 2017 at 0:2 Comment(1)
Such an interesting question and still no answers. Did you make any progress with this? You might want to just post whatever you did as an answer to your own question to share with others.Manufacturer
N
0

The headers way

There does not seem to be a "correct" answer for this. That being said, I would go with the headers way.

You can easily block off unknown headers as preflight checks. You can change the allow list of headers for you service to block off headers that are not used by the service.

Access-Control-Allow-Headers: [<header-name>[, <header-name>]*]
Access-Control-Allow-Headers: *

To see the list of headers allowed by your service, make a call to it and check the response headers and search for Access-Control-Allow-Headers header field.

Let's say you have three services, Cat, Dog and Animal. Animal being the caller service which calls the Cat service and Dog service.

Dog -> Access-Control-Allow-Headers: [....,"X-Request-Dry-Run",..] // dog accepts the header Cat -> Access-Control-Allow-Headers: [.....] // cat doesn't accept the 'dry-run' header

Now when caller calls the Cat service which X-Request-Dry-Run: true header, it gets a request error.

MDN Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers

Comparisons

Passing a query parameter could pass a flag as a query parameter but the request still goes through if the api doesn't know of the parameter.

It's generally not a convention to mix post body and query params in a post request.

Exposing a dry-run api just for validating This solution works as I can verify dry-run version of the URL exists or not but I don't want to expose more endpoints just for validation

APIs have clashing paths.

Inject the flag to the body of resource This looks to be a solution but when the api doesn't support this field, JSON serialization will fail. In that case, I can't tell whether it is because dry-run is not supported by the api or there is actually a problem in the body. Also, it doesn't feel right since dry-run is not a part of the resource.

Agreed

Nightgown answered 19/10, 2022 at 4:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.