0

I'm wondering if the following structure of API links is HATEOAS compatible?

Especially I'm not sure of /create endpoint. Should it be at the entry level because user can create a group from there or is it fine to put it in /groups?

What are your thoughts about the rest? It should be also HAL compatible.

/groups
  /create
  /detail/{groupId}
    /update
    /delete
    /items
  /search{?page,size,sort}
Alexandru Marculescu
  • 5,569
  • 6
  • 34
  • 50
Paweł O.
  • 57
  • 8
  • 2
    Why do you put operations (`create`, `detail`, `update`, `delete`, `search`) into URIs? That's RPC, not REST. –  Jun 21 '16 at 06:49
  • 1
    I realised it should be just POST /groups - to create group PUT /detail/{groupID} - to update group DELETE /detail/{groupID} - to delete group – Paweł O. Jun 22 '16 at 07:41
  • 1
    Yes, that would be better. –  Jun 22 '16 at 07:47
  • But shouldn't _links provide this kind of URI's anyway? – Paweł O. Jun 22 '16 at 07:48
  • 1
    But the URIs must not change. Then HTTP verb can change. –  Jun 22 '16 at 07:49
  • I get it, but is that bad practice to provide GET /detail/{groupId} response with update and delete links which in this case would be the same as the parent? – Paweł O. Jun 22 '16 at 07:51
  • 1
    No, since the the HTTP verb to be used and specified with the link will be different. –  Jun 22 '16 at 07:52
  • I can implement other HTTP verb on frontend side. I think this kind of information (update/delete links) still provides some information "what we can do in current state". Am I wrong? By the way - any good articles about a use of OPTIONS method? – Paweł O. Jun 22 '16 at 08:01

1 Answers1

1

HATEOAS (see Richardson's Maturity Model level 3) is all about links, so with HAL Browser this would look something like this:

Root:

{
  "_links": {
    "self": {
      "href": "/api/root"
    },
    "api:group-add": {
      "href": "http://apiname:port/api/group"
    },
    "api:group-search": {
      "href": "http://apiname:port/api/group?pageNumber={pageNumber}&pageSize={pageSize}&sort={sort}"
    },
    "api:group-by-id": {
      "href": "http://apiname:port/api/group/id" (OR "href": "http://apiname:port/api/group?id={id}")
    }
  }
}

The add would simply be a POST to that endpoint, and then you'd have 2 GET methods.

Then once you drill down to a particular group (say #1):

{
  "Id" : 1,
  "Name" : "test",
  "_links": {
    "self": {
      "href": "/api/group/1" (OR "/api/group?id=1")
    },
    "edit": {
      "href": "http://apiname:port/api/group/1"
    },
    "api:delete": {
      "href": "http://apiname:port/api/group/1"
    },
    "api:items-query": {
      "href": "http://apiname:port/api/bonus?groupId=1"
    }
  }
}

Here, the edit would simply be a PUT, and then you'll need a DELETE (see level 2 of REST in that same link), as for the items, you probably know best if they are just a property, or another endpoint; you could even embed them to be returned in the same call that's retrieving a group.

Alexandru Marculescu
  • 5,569
  • 6
  • 34
  • 50