Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API - Endpoint syntax - get item by property - not by id

Tags:

rest

I'm implementing my first REST API, and I have a question about the syntax of the URL endpoints.

I know that I should use these endpoint for get, create, update and delete:

  • Get list of items
    Method: GET, Url: /api/items

  • Get item by id
    Method: GET, Url: /api/items/:id

  • Add item (new item data in the request body)
    Method: POST, Url: /api/items

  • Modify item (modified item data in the request body)
    Method: PUT, Url: /api/items/:id

  • Delete item
    Method: DELETE, Url: /api/items/:id

But lets say the interface of item is

interface item
{
  id: string;
  name: string;
}

What should be the request url for getting an item by it's name?
I can't use Method: GET, Url: /api/items/:name, because this will match the get-by-id request. So how should I syntax this endpoint?

like image 956
Gil Epshtain Avatar asked Aug 03 '19 14:08

Gil Epshtain


2 Answers

There is no standard REST URI syntax unless you are doing OData for example. You have perfect freedom designing your own URIs, even /resource/{id} is perfectly valid.

What I like to do is end the URIs of collections with / and use queries for filtering collections. So I would do /api/{version}/items/?name={name} if they have unique names and you expect an item instead of a collection, then I would do it this way: /api/{version}/items/name:{name}. But this is my style.

From client perspective the URI syntax is totally irrelevant, because the server gives the valid URI templates to the client according to the HATEOES constraint. If you thought otherwise, then probably you are building a CRUD API instead of a REST API.

like image 184
inf3rno Avatar answered Oct 03 '22 12:10

inf3rno


You chould use a filter on the collections endpoint like:

Method: GET, Url: /api/items?name=foo

This filter could return all items which have a foo string in them (depending on how you want to handle wildcards in the search / filter term), e.g. the response could be a collection of items:

{
    "data": [
        {
            "id": "d079d8e9-4d24-4514-b356-78587f6c2ba9",
            "name": "foo"
        },
        {
            "id": "7f5e558c-6a7f-4ebe-8f4f-a2d029a803ed",
            "name": "foo bar" 
        }  
    ]
}

If you want the response to return a single resource you could also use the name as identifier and apply the scheme from above using the name, e.g.

Method: GET, Url: /api/items/:name

like image 22
lordrhodos Avatar answered Oct 03 '22 13:10

lordrhodos