REST API - How to query for links discovery?
up vote
2
down vote
favorite
Suppose I have a RESTful HATEOAS API which has /posts
endpoint which lists posts with a query shortcut /posts/new
. How do I query the API to discover /posts/new
?
My ideas:
1) Query /posts
and get links from _links
attribute (and the entities listed are necessary overhead):
GET /posts
{
"docs": [
...
]
"_links": {
"new": { "rel": "posts", "href": "/posts/new" }
}
}
2) Provide this in the API root together with list of resources:
GET /
{
"resources": {
"posts": {
"_links": {
"self": { "rel": "posts", "href": "/posts" }
"new": { "rel": "posts", "href": "/posts/new" }
}
}
}
}
3) I should not use the /posts/new
query and instead use /posts
and query params. However, if I change my server logic I would have to change client logic too and that would be serve-client coupling. For example:
- New messages will be requested by client by somehow providing parameter
timestamp > (today - 30)
- I introduce
draft
property and change my idea that new are only the posts withtimestamp > (today - 30) && draft = false
- I have to change client to add drafts constraint
Note: posts is just an example I am asking in general.
rest hateoas
add a comment |
up vote
2
down vote
favorite
Suppose I have a RESTful HATEOAS API which has /posts
endpoint which lists posts with a query shortcut /posts/new
. How do I query the API to discover /posts/new
?
My ideas:
1) Query /posts
and get links from _links
attribute (and the entities listed are necessary overhead):
GET /posts
{
"docs": [
...
]
"_links": {
"new": { "rel": "posts", "href": "/posts/new" }
}
}
2) Provide this in the API root together with list of resources:
GET /
{
"resources": {
"posts": {
"_links": {
"self": { "rel": "posts", "href": "/posts" }
"new": { "rel": "posts", "href": "/posts/new" }
}
}
}
}
3) I should not use the /posts/new
query and instead use /posts
and query params. However, if I change my server logic I would have to change client logic too and that would be serve-client coupling. For example:
- New messages will be requested by client by somehow providing parameter
timestamp > (today - 30)
- I introduce
draft
property and change my idea that new are only the posts withtimestamp > (today - 30) && draft = false
- I have to change client to add drafts constraint
Note: posts is just an example I am asking in general.
rest hateoas
1
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the_links
here on the top-level.
– Roman Vottner
Nov 9 at 12:07
In spite of my question, does this mean I should discover the alias/posts/new
by querying/posts
and reading the_links
property?
– SmallhillCZ
Nov 9 at 13:44
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to benew
.
– yaccob
Nov 18 at 0:09
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Suppose I have a RESTful HATEOAS API which has /posts
endpoint which lists posts with a query shortcut /posts/new
. How do I query the API to discover /posts/new
?
My ideas:
1) Query /posts
and get links from _links
attribute (and the entities listed are necessary overhead):
GET /posts
{
"docs": [
...
]
"_links": {
"new": { "rel": "posts", "href": "/posts/new" }
}
}
2) Provide this in the API root together with list of resources:
GET /
{
"resources": {
"posts": {
"_links": {
"self": { "rel": "posts", "href": "/posts" }
"new": { "rel": "posts", "href": "/posts/new" }
}
}
}
}
3) I should not use the /posts/new
query and instead use /posts
and query params. However, if I change my server logic I would have to change client logic too and that would be serve-client coupling. For example:
- New messages will be requested by client by somehow providing parameter
timestamp > (today - 30)
- I introduce
draft
property and change my idea that new are only the posts withtimestamp > (today - 30) && draft = false
- I have to change client to add drafts constraint
Note: posts is just an example I am asking in general.
rest hateoas
Suppose I have a RESTful HATEOAS API which has /posts
endpoint which lists posts with a query shortcut /posts/new
. How do I query the API to discover /posts/new
?
My ideas:
1) Query /posts
and get links from _links
attribute (and the entities listed are necessary overhead):
GET /posts
{
"docs": [
...
]
"_links": {
"new": { "rel": "posts", "href": "/posts/new" }
}
}
2) Provide this in the API root together with list of resources:
GET /
{
"resources": {
"posts": {
"_links": {
"self": { "rel": "posts", "href": "/posts" }
"new": { "rel": "posts", "href": "/posts/new" }
}
}
}
}
3) I should not use the /posts/new
query and instead use /posts
and query params. However, if I change my server logic I would have to change client logic too and that would be serve-client coupling. For example:
- New messages will be requested by client by somehow providing parameter
timestamp > (today - 30)
- I introduce
draft
property and change my idea that new are only the posts withtimestamp > (today - 30) && draft = false
- I have to change client to add drafts constraint
Note: posts is just an example I am asking in general.
rest hateoas
rest hateoas
edited Nov 9 at 11:34
asked Nov 9 at 11:11
SmallhillCZ
588
588
1
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the_links
here on the top-level.
– Roman Vottner
Nov 9 at 12:07
In spite of my question, does this mean I should discover the alias/posts/new
by querying/posts
and reading the_links
property?
– SmallhillCZ
Nov 9 at 13:44
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to benew
.
– yaccob
Nov 18 at 0:09
add a comment |
1
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the_links
here on the top-level.
– Roman Vottner
Nov 9 at 12:07
In spite of my question, does this mean I should discover the alias/posts/new
by querying/posts
and reading the_links
property?
– SmallhillCZ
Nov 9 at 13:44
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to benew
.
– yaccob
Nov 18 at 0:09
1
1
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the
_links
here on the top-level.– Roman Vottner
Nov 9 at 12:07
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the
_links
here on the top-level.– Roman Vottner
Nov 9 at 12:07
In spite of my question, does this mean I should discover the alias
/posts/new
by querying /posts
and reading the _links
property?– SmallhillCZ
Nov 9 at 13:44
In spite of my question, does this mean I should discover the alias
/posts/new
by querying /posts
and reading the _links
property?– SmallhillCZ
Nov 9 at 13:44
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to be
new
.– yaccob
Nov 18 at 0:09
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to be
new
.– yaccob
Nov 18 at 0:09
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
In a REST architecture URIs should be discovered via their accompanying link-relation name. On interpreting your examples above as HAL the URI /post/new
has a link-relation name of new
. Link relation names provide semantics to URIs which allow clients to determine when to invoke these URIs. HAL is just one of a handful JSON-based media types that support HATEOAS. There are further media-types available that provide a similar job with slightly different syntax and capabilities.
Upon receiving such a document a client would parse the message and build some context for the message containing the actual content including additional metadata like links and further embedded data. If it wants to retrieve the list of the most recent posts it basically needs to look up the key (link-relation name) that expresses the intent (new
in your case) from the before-mentioned context in order to retrieve the assigned value (URI). How a client maintains this context is some implementation detail. It might build up a tree-map for easier lookup of "link-relation" keys and their values (URIs) or use some totally different approach.
The knowledge what key to use needs to be present somehow. As link relations express certain semantics they need to be specified somewhere. This can happen in industry standards or media-type definitions. IANA maintains a list of standardized link-relation names and their semantics. On examining the list probably the most likely match according to your specification is current
which is defined as
Refers to a resource containing the most recent item(s) in a collection of resources.
I'd therefore propose to change the link-relation name from new
to current
.
add a comment |
up vote
-1
down vote
Well, the whole point of the RESTFUL is to make the links discovery easy by making them correspond to the HTTP method used by the client. That means all your links would be simply named /post
, the only thing that would change is the htpp method and the parameters they take, which your server would use to determine the actual operation the client wants.
This is a sample from a C# project (notice that the links are all the same, the only changes are the HTTP_METHOD
and/or the parameter passed):
List of common http methods: POST, GET, PUT, DELETE
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
In a REST architecture URIs should be discovered via their accompanying link-relation name. On interpreting your examples above as HAL the URI /post/new
has a link-relation name of new
. Link relation names provide semantics to URIs which allow clients to determine when to invoke these URIs. HAL is just one of a handful JSON-based media types that support HATEOAS. There are further media-types available that provide a similar job with slightly different syntax and capabilities.
Upon receiving such a document a client would parse the message and build some context for the message containing the actual content including additional metadata like links and further embedded data. If it wants to retrieve the list of the most recent posts it basically needs to look up the key (link-relation name) that expresses the intent (new
in your case) from the before-mentioned context in order to retrieve the assigned value (URI). How a client maintains this context is some implementation detail. It might build up a tree-map for easier lookup of "link-relation" keys and their values (URIs) or use some totally different approach.
The knowledge what key to use needs to be present somehow. As link relations express certain semantics they need to be specified somewhere. This can happen in industry standards or media-type definitions. IANA maintains a list of standardized link-relation names and their semantics. On examining the list probably the most likely match according to your specification is current
which is defined as
Refers to a resource containing the most recent item(s) in a collection of resources.
I'd therefore propose to change the link-relation name from new
to current
.
add a comment |
up vote
0
down vote
In a REST architecture URIs should be discovered via their accompanying link-relation name. On interpreting your examples above as HAL the URI /post/new
has a link-relation name of new
. Link relation names provide semantics to URIs which allow clients to determine when to invoke these URIs. HAL is just one of a handful JSON-based media types that support HATEOAS. There are further media-types available that provide a similar job with slightly different syntax and capabilities.
Upon receiving such a document a client would parse the message and build some context for the message containing the actual content including additional metadata like links and further embedded data. If it wants to retrieve the list of the most recent posts it basically needs to look up the key (link-relation name) that expresses the intent (new
in your case) from the before-mentioned context in order to retrieve the assigned value (URI). How a client maintains this context is some implementation detail. It might build up a tree-map for easier lookup of "link-relation" keys and their values (URIs) or use some totally different approach.
The knowledge what key to use needs to be present somehow. As link relations express certain semantics they need to be specified somewhere. This can happen in industry standards or media-type definitions. IANA maintains a list of standardized link-relation names and their semantics. On examining the list probably the most likely match according to your specification is current
which is defined as
Refers to a resource containing the most recent item(s) in a collection of resources.
I'd therefore propose to change the link-relation name from new
to current
.
add a comment |
up vote
0
down vote
up vote
0
down vote
In a REST architecture URIs should be discovered via their accompanying link-relation name. On interpreting your examples above as HAL the URI /post/new
has a link-relation name of new
. Link relation names provide semantics to URIs which allow clients to determine when to invoke these URIs. HAL is just one of a handful JSON-based media types that support HATEOAS. There are further media-types available that provide a similar job with slightly different syntax and capabilities.
Upon receiving such a document a client would parse the message and build some context for the message containing the actual content including additional metadata like links and further embedded data. If it wants to retrieve the list of the most recent posts it basically needs to look up the key (link-relation name) that expresses the intent (new
in your case) from the before-mentioned context in order to retrieve the assigned value (URI). How a client maintains this context is some implementation detail. It might build up a tree-map for easier lookup of "link-relation" keys and their values (URIs) or use some totally different approach.
The knowledge what key to use needs to be present somehow. As link relations express certain semantics they need to be specified somewhere. This can happen in industry standards or media-type definitions. IANA maintains a list of standardized link-relation names and their semantics. On examining the list probably the most likely match according to your specification is current
which is defined as
Refers to a resource containing the most recent item(s) in a collection of resources.
I'd therefore propose to change the link-relation name from new
to current
.
In a REST architecture URIs should be discovered via their accompanying link-relation name. On interpreting your examples above as HAL the URI /post/new
has a link-relation name of new
. Link relation names provide semantics to URIs which allow clients to determine when to invoke these URIs. HAL is just one of a handful JSON-based media types that support HATEOAS. There are further media-types available that provide a similar job with slightly different syntax and capabilities.
Upon receiving such a document a client would parse the message and build some context for the message containing the actual content including additional metadata like links and further embedded data. If it wants to retrieve the list of the most recent posts it basically needs to look up the key (link-relation name) that expresses the intent (new
in your case) from the before-mentioned context in order to retrieve the assigned value (URI). How a client maintains this context is some implementation detail. It might build up a tree-map for easier lookup of "link-relation" keys and their values (URIs) or use some totally different approach.
The knowledge what key to use needs to be present somehow. As link relations express certain semantics they need to be specified somewhere. This can happen in industry standards or media-type definitions. IANA maintains a list of standardized link-relation names and their semantics. On examining the list probably the most likely match according to your specification is current
which is defined as
Refers to a resource containing the most recent item(s) in a collection of resources.
I'd therefore propose to change the link-relation name from new
to current
.
answered Nov 9 at 15:48
Roman Vottner
5,48112436
5,48112436
add a comment |
add a comment |
up vote
-1
down vote
Well, the whole point of the RESTFUL is to make the links discovery easy by making them correspond to the HTTP method used by the client. That means all your links would be simply named /post
, the only thing that would change is the htpp method and the parameters they take, which your server would use to determine the actual operation the client wants.
This is a sample from a C# project (notice that the links are all the same, the only changes are the HTTP_METHOD
and/or the parameter passed):
List of common http methods: POST, GET, PUT, DELETE
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
add a comment |
up vote
-1
down vote
Well, the whole point of the RESTFUL is to make the links discovery easy by making them correspond to the HTTP method used by the client. That means all your links would be simply named /post
, the only thing that would change is the htpp method and the parameters they take, which your server would use to determine the actual operation the client wants.
This is a sample from a C# project (notice that the links are all the same, the only changes are the HTTP_METHOD
and/or the parameter passed):
List of common http methods: POST, GET, PUT, DELETE
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
add a comment |
up vote
-1
down vote
up vote
-1
down vote
Well, the whole point of the RESTFUL is to make the links discovery easy by making them correspond to the HTTP method used by the client. That means all your links would be simply named /post
, the only thing that would change is the htpp method and the parameters they take, which your server would use to determine the actual operation the client wants.
This is a sample from a C# project (notice that the links are all the same, the only changes are the HTTP_METHOD
and/or the parameter passed):
List of common http methods: POST, GET, PUT, DELETE
Well, the whole point of the RESTFUL is to make the links discovery easy by making them correspond to the HTTP method used by the client. That means all your links would be simply named /post
, the only thing that would change is the htpp method and the parameters they take, which your server would use to determine the actual operation the client wants.
This is a sample from a C# project (notice that the links are all the same, the only changes are the HTTP_METHOD
and/or the parameter passed):
List of common http methods: POST, GET, PUT, DELETE
answered Nov 9 at 11:47
WoF_Angel
1,22682245
1,22682245
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
add a comment |
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Yes, but whole point of HATEAOS and REST is that the api is entirely discoverable by links provided and that the client should (in theory) not need anything other, than the entry endpoint. By this there has to be no definition of the API on the client as all the URLs used are provided by the API itself. "[...] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API" (roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)
– SmallhillCZ
Nov 9 at 13:17
Aliases for common queries (as is
/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)– SmallhillCZ
Nov 9 at 13:20
Aliases for common queries (as is
/posts/new
) are then recommended by many. (kennethlange.com/rest-api-checklist, snyxius.com/21-best-practices-designing-launching-restful-api, vinaysahni.com/best-practices-for-a-pragmatic-restful-api)– SmallhillCZ
Nov 9 at 13:20
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
I can't see how this answer addresses the question.
– yaccob
Nov 18 at 0:12
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53224620%2frest-api-how-to-query-for-links-discovery%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This depends on what representation format the client askes for. As the given samples are similar to HAL JSON I'd keep the
_links
here on the top-level.– Roman Vottner
Nov 9 at 12:07
In spite of my question, does this mean I should discover the alias
/posts/new
by querying/posts
and reading the_links
property?– SmallhillCZ
Nov 9 at 13:44
Did you consider adding the query parameters to the link returned by the service? This way your option 3 would no longer couple client logic to server logic. The client could blindly use the link (that includes query parameters) regardless of what the service considers to be
new
.– yaccob
Nov 18 at 0:09