restapi-designrestful-url

What should be returned from an API endpoint that accepts a list of resource IDs but one of the passed IDs does not exist


I have an API endpoint that returns multiple resources which can be filtered by a URL parameter. An example is below and all of the IDs are in the correct format.

http://localhost:8000/products?ids=1,2,3,4,5

However, the resource with the ID of 4 does not exists (in the database for example). I could do the following:

Are any of the above viable options or is there a better solution? On the frontend, I will display a list of resources only if all of the requested resources were found so need to know if they all were returned or not.


Solution

  • I think the answer depends on whether the partial content is satisfiable for the clients. If not, then better to return a 4xx header without content.

    If you want to serve partial content, then you can use the 206 partial content with range headers or the 207 multi-status on these scenarios. The multi-status might be the better option.

    Here is an example about the multi-status:

    HTTP/1.1 207 Multi-Status
    Content-Type: application/json
    
    {
      "results": [
        {
          "href": "/batch/5/item/1",
          "status": 200
        },
        {
          "href": "/batch/5/item/2",
          "status": 200
        },
        {
          "href": "/batch/5/item/3",
          "status": 400
        },
        {
          "href": "/batch/5/item/4",
          "status": 403
        }
    }
    

    https://evertpot.com/http/207-multi-status

    With the 206 you need a custom ranging solution with the range headers. It can be done, but typically it is used for byte ranges, not for ids.

    GET http://localhost:8000/products
    Range: ids=1,2,3,4,5
    
    HTTP/1.1 206 Partial Content
    Content-Type: application/json
    Content-Range: ids=1,4,5
    
    {
      "results": [
        {
          "href": "/batch/5/item/1"
        },
        {
          "href": "/batch/5/item/4"
        },
        {
          "href": "/batch/5/item/5"
        }
    }
    

    https://www.belugacdn.com/blog/cdn/206-partial-content-error/

    Though you can return 416 Range Not Satisfiable in these cases too.