Implementing the REST Hypermedia Constraint with a two backend services - html

I am trying to build a system that uses nodejs with express to render html pages based on data from another backend service. The backend service provides JSON data that the nodejs server uses to render the html and then pass to the browser. Having read up on REST and the Hyemedia constraint I want to use this in the design, but can not seem to figure it out. A simple example would be a page that provides a list of items in which each item is a link that can be clicked on to get the full details of that item. So the backend service might make some JSON that looks like
{
"title": "List of items"
"self": "http://api.hostname.com/items
[
{
"title":"item1",
"url": "http://api.hostname.com/items/1
}
{
"title":"item2",
"url": "http://api.hostname.com/items/2
} {
"title":"item3",
"url": "http://api.hostname.com/items/3
}
}
I then have nodejs render a page in html with a list of links using "title" for the name. The issue is then I don't know what to use for the href. It would work if the href is to a view that with render the item like
href="/items/2
but I have no way of pass the "url" field back to node so node can pass that to the backend service. I end up building the url for the backend service based on the view url. Which if I understand REST is not the Hypermedia way. It means my node code has to know the format of the urls of the backend service instead of getting the urls and using directly.
So is there so clever feature like adding the "url" field as a query parameter of the href to preserve it on the client? I am misunderstanding the Hypermedia Constraint or should I being trying to use it at all?

Whether you should use the hypermedia constraint is a matter of opinion. (I have a blog post stating my own opinion).
As a more specific answer, I'll point out that you actually have 2 separate REST systems in this application, one of which is serving html and one of which is serving json. If they are equivalent in functionality, the hypermedia constraint would expect that they actually be a single system, where requests could return different media types based on the Accepts http header. This eliminates your problem (because the urls become the same).

Related

How to get clean JSON response for node/{nid} in Drupal 8?

I am trying to get a clean JSON response for nodes in Drupal 8 like:
{
"title":"big news happens somethere",
"body":"a lot of description here",
"tag":[
"news",
"story"
]
}
I know one way is to use the views rest display, where I can specify the column name alias. But with that, I will get a JSON array with count being 1 for that single node.
How can I get exactly n JSON object with a clean schema structure for that?
RESTful Web Services and RESTui can deliver what you need.
The other option is to make a custom module with a custom page and deliver content the way you want.
I recommend using the RESTful Web Services module that's included with Drupal 8. Check out the following articles:
http://enzolutions.com/articles/2014/12/16/how-to-create-a-rest-resource-in-drupal-8/
https://www.mediacurrent.com/blog/eight-insights-and-useful-snippets-d8-rest-module

how should Hateoas be handled from frontend?

I have this question that has been going around through my head for a while. Lets suppose we have structured our project with backend and frontend on separate layers. So, from the frontend, we want to get a costumer, which comes on hal+json format:
GET /customers/1 HTTP/1.1
Accept: application/hal+json
{
"name": "Alice",
"links": [ {
"rel": "self",
"href": "http://localhost:8080/customer/1"
} {
"rel": "transactions",
"href": "http://localhost:8080/customer/1/transactions"
}]
}
Then, from the frontend i want to get all customer transactions. My question is: how should i get the url? should it be from the response? or should i build it internally?
if we go with first option, i think that maybe that wouldn't be elegant to iterate all links until we get that one we want. Also, there could happen the situation where we don't have the link of the request we want to do.
if we go with second option, i don't understand how to build that url if we don't actually have the ids. How could i create new customer transactions if hateoas replaces ids with links and i haven't got the object reference in the body anymore?
I thought that maybe service should support both application/hal+json(oriented to users) and application/json(oriented to clients) but i don't see that this is how is making it done generally.
What do you think?
Definitely the first option. Namely, since HATEOAS is a final stage of Richardson Maturity Model, clients are expected to follow the provided links, not to build the URLs by themselves:
The point of hypermedia controls is that they tell us what we can do
next, and the URI of the resource we need to manipulate to do it.
Rather than us having to know where to post our appointment request,
the hypermedia controls in the response tell us how to do it.
What benefits does this bring? I can think of at least two:
Simple upgrade of the REST API - server-side developers can change the URIs of the resources, without breaking the client-side code because clients just follow the provided links; additionally, server-side developers can easily add new links
Robustness - by following the links, client-side code would never try to access the broken links, misspelled links etc.
Q: Also, there could happen the situation where we don't have the link of the request we want to do?
It is up to API designer to ensure that all required links are provided. Front-end developer shouldn't worry about that.
See also:
Rest lesson learned - avoid hackable URLs
HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. You can have a look on Spring HATEOAS documentation for instance :
https://spring.io/understanding/HATEOAS
Another link about it using Spring and AngularJS is available here:
AngularJS and Spring HATEOAS tutorial
This one seems to be good enough and handles your use case.
Regards, André

Whats the REST way of showing forms to user

I was reading this Questions regarding REST
What exactly is RESTful programming?
While reading i get that the client is independent of server and client don't need to construct anything.
I want to know that when we are building forms like user registration . Then what is the REST way of doing it.
I mean when i do GET for /user/new then
Does the server has to send the complete FORM in html
Only send fields in JSON and form is constructed by client itself
But then again there will be many complexities, if i just send the fields, then what things like
Hidden fields
Default value for select boxes
what about some logic like this field can'r be greater than 30 etc
REST is, as you're already aware, a way of communicating between a client and a server. However, the issue here is what is being defined as the "client". Personally, I tend to consider that the browser itself is not in itself the client: instead, the client is written in JavaScript, and the browser is merely a conduit to executing it.
Say for the sake of argument that you wish to view the details of user '1414'. The browser would be directed to the following location:
/UserDetails.html#1414
This would load the static file ViewUser.html, containing all the form fields that may be necessary, as well as (via a <script> tag) your JavaScript client. The client would load, look at the URL and make a RESTful call to:
GET /services/Users/1414
which would send back JSON data relating to that user. When the user then hits "save", the client would then make the following call:
PUT /services/Users/1414
to store the data.
In your example, you wanted to know how this would work with a new user. The URL that the browser would be directed to would be:
/UserDetails.html#0
(or #new, or just # - just something to tell the JavaScript that this is a new client. This isn't a RESTful URL so the precise details are irrelevant).
The browser would again load the static file ViewUser.html and your JavaScript client, but this time no GET would be made on the Users service - there is no user to download. In addition, when the user is saved, this time the call would be:
POST /services/Users/
with the service ideally returning a 302 to /services/Users/1541 - the location of the object created. Note that as this is handled in the client not the browser, no actual redirection occurs.
"Forms" for hypermedia APIs could be rendered in a "forms aware" media type like for instance Mason (https://github.com/JornWildt/Mason), Hydra (http://www.markus-lanthaler.com/hydra/) or Sirene (https://github.com/kevinswiber/siren). In Mason (which is my project) you could have a "create user" action like this:
{
"#actions": {
"create-user": {
"type": "json",
"href": "... URL to resource accepting the POST ...",
"method": "POST",
"title": "Create new user",
"schemaUrl": "... Optional URL to JSON schema definition for input ..."
"template": {
"Windows Domain": "acme"
}
}
}
}
The client can GET a resource that include the above action, find it be the name "create-user" and in this way be told which method to use, where to apply it, how the payload should be formated (in this case its JSON as described by an external schema definition) and some default values (the "template" object).
If you need more complex descriptions (like selection lists and validation rules as you mention) then you are on your own and will have to encoded that information in your own data - or use HTML or XForms.
There are multiple ways to do what you want.
You can use GET for /user/new along with a create-form link relation to get a single link. This can in plain HTML or HTML fragment, or a schema description, practically anything you want (the result will be less reusable than the other solutions).
You can use a standard MIME type which supports form descriptions. For example HAL with a form extension or collection+json.
You can use an RDF format, like JSON-LD with a proper vocab like Hydra.

RESTful Collection Resources - idiomatic JSON representations and roundtripping

I have a collection resource called Columns. A GET with Accept: application/json can't directly return a collection, so my representation needs to nest it in a property:-
{ "propertyName": [
{ "Id": "Column1", "Description": "Description 1" },
{ "Id": "Column2", "Description": "Description 2" }
]
}
Questions:
what is the best name to use for the identifier propertyName above? should it be:
d (i.e. is d an established convention or is it specific to some particular frameworks (MS WCF and MS ASP.NET AJAX ?)
results (i.e. is results an established convention or is it specific to some particular specifications (MS OData)?)
Columns (i.e. the top level property should have a clear name and it helps to disambiguate my usage of generic application/json as the Media Type)
NB I feel pretty comfortable that there should be something wrapping it, and as pointed out by #tuespetre, XML or any other representation would force you to wrap it to some degree anyway
when PUTting the content back, should the same wrapping in said property be retained [given that it's not actually necessary for security reasons and perhaps conventional JSON usage idioms might be to drop such nesting for PUT and POST given that they're not necessary to guard against scripting attacks] ?
my gut tells me it should be symmetric as for every other representation but there may be prior art for dropping the d/*results** [assuming that's the answer to part 1]*
... Or should a PUT-back (or POST) drop the need for a wrapping property and just go with:-
[
{ "Id": "Column1", "Description": "Description 1" },
{ "Id": "Column2", "Description": "Description 2" }
]
Where would any root-level metadata go if one wished to add that?
How/would a person crafting a POST Just Know that it needs to be symmetric?
EDIT: I'm specifically interested in an answer that with a reasoned rationale that specifically takes into account the impacts on client usage with JSON. For example, HAL takes care to define a binding that makes sense for both target representations.
EDIT 2: Not accepted yet, why? The answers so far don't have citations or anything that makes them stand out over me doing a search and picking something out of the top 20 hits that seem reasonable. Am I just too picky? I guess I am (or more likely I just can't ask questions properly :D). Its a bit mad that a week and 3 days even with an )admittedly measly) bonus on still only gets 123 views (from which 3 answers ain't bad)
Updated Answer
Addressing your questions (as opposed than going off on a bit of a tangent in my original answer :D), here's my opinions:
1) My main opinion on this is that I dislike d. As a client consuming the API I would find it confusing. What does it even stand for anyway? data?
The other options look good. Columns is nice because it mirrors back to the user what they requested.
If you are doing pagination, then another option might be something like page or slice as it makes it clear to the client, that they are not receiving the entire contents of the collection.
{
"offset": 0,
"limit": 100,
"page" : [
...
]
}
2) TBH, I don't think it makes that much difference which way you go for this, however if it was me, I probably wouldn't bother sending back the envelope, as I don't think there is any need (see below) and why make the request structure any more complicated than it needs to be?
I think POSTing back the envelope would be odd. POST should let you add items into the collection, so why would the client need to post the envelope to do this?
PUTing the envelope back could make sense from a RESTful standpoint as it could be seen as updating metadata associated with the collection as a whole. I think it is worth thinking about the sort of meta data you will be exposing in the envelope. All the stuff I think would fit well in this envelope (like pagination, aggregations, search facets and similar meta data) is all read only, so it doesn't make sense for the client to send this back to the server. If you find yourself with a lot of data in the envelope that the client is able to mutate - then it could be a sign to break that data out into a separate resource with the list as a sub collection. Rubbish example:
/animals
{
"farmName": "farm",
"paging": {},
"animals": [
...
]
}
Could be broken up into:
/farm/1
{
"id": 1,
"farmName": "farm"
}
and
/farm/1/animals
{
"paging": {},
"animals": [
...
]
}
Note: Even with this split, you could still return both combined as a single response using something like Facebook's or LinkedIn's field expansion syntax. E.g. http://example.com/api/farm/1?field=animals.offset(0).limit(10)
In response, to your question about how the client should know what the JSON payload they are POSTing and PUTing should look like - this should be reflected in your API documentation. I'm not sure if there is a better tool for this, but Swagger provides a spec that allows you to document what your request bodies should look like using JSON Schema - check out this page for how to define your schemas and this page for how to reference them as a parameter of type body. Unfortunately, Swagger doesn't visualise the request bodies in it's fancy web UI yet, but it's is open source, so you could always add something to do this.
Original Answer
Check out William's comment in the discussion thread on that page - he suggests a way to avoid the exploit altogether which means you can safely use a JSON array at the root of your response and then you need not worry about either of you questions.
The exploit you link to relies on your API using a Cookie to authenticate a user's session - just use a query string parameter instead and you remove the exploit. It's probably worth doing this anyway since using Cookies for authentication on an API isn't very RESTful - some of your clients may not be web browsers and may not want to deal with cookies.
Why Does this fix work?
The exploit is a form of CSRF attack which relies on the attacker being able to add a script tag on his/her own page to a sensitive resource on your API.
<script src="http://mysite.com/api/columns"></script>
The victims web browser will send all Cookies stored under mysite.com to your server and to your servers this will look like a legitimate request - you will check the session_id cookie (or whatever your server-side framework calls the cookie) and see the user is authenticated. The request will look like this:
GET http://mysite.com/api/columns
Cookie: session_id=123456789;
If you change your API you ignore Cookies and use a session_id query string parameter instead, the attacker will have no way of tricking the victims web browser into sending the session_id to your API.
A valid request will now look like this:
GET http://mysite.com/api/columns?session_id=123456789
If using a JavaScript client to make the above request, you could get the session_id from a cookie. An attacker using JavaScript from another domain will not be able to do this, as you cannot get cookies for other domains (see here).
Now we have fixed the issue and are ignoring session_id cookies, the script tag on the attackers website will still send a similar request with a GET line like this:
GET http://mysite.com/api/columns
But your server will respond with a 403 Forbidden since the GET is missing the required session_id query string parameter.
What if I'm not authenticating users for this API?
If you are not authenticating users, then your data cannot be sensitive and anyone can call the URI. CSRF should be a non-issue since with no authentication, even if you prevent CSRF attacks, an attacker could just call your API server side to get your data and use it in anyway he/she wants.
I would go for 'd' because it clearly separates the 'envelope' of your resource from its content. This would also make it easier for consumers to parse your responses, as opposed to 'guessing' the name of the wrapping property of a given resource before being able to access what it holds.
I think you're talking about two different things:
POST request should be sent in application/x-www-form-urlencoded. Your response should basically mirror a GET if you choose to include a representation of the newly created resource in your reply. (not mandatory in HTTP).
PUTs should definitely be symmetric to GETs. The purpose of a PUT request is to replace an existing resource representation with another. It just makes sense to have both requests share the same conventions, doesn't it?
Go with 'Columns' because it is semantically meaningful. It helps to think of how JSON and XML could mirror each other.
If you would PUT the collection back, you might as well use the same media type (syntax, format, what you will call it.)

How to send HTML form RESTfully?

I have a URI for a collection of resources called 'facts', and URIs for each 'fact' resource in that collection.
The form for creating a new 'fact' should be requested with a GET, I believe, but I'm having trouble deciding what URI it should be made to.
A GET to the collection URI should return a list of the 'fact' resource URIs. Each 'fact' URI should return its contents as a response to GET. The actual 'fact' creation would be a POST (or PUT, depending on the situation), of course.
I see a few options, but none seem satisfactory:
Add a 'fact form' URI which the 'facts' URI will reference. A GET to this URI gives the HTML form. Seems wrong to have another resource just for a description of a resource.
A POST made to the 'facts' URI without including any form data in the headers would return the form. Then after the user fills the form in, it would POST with the form data, and create the new 'fact' resource. This seems like an even worse approach.
Don't send the form over the wire, but include it as part of the API. This seems RESTful since a REST API should describe the media types, and a form can be made from a description of the 'fact' type. This is weird to implement. Maybe the REST service is separate from the regular web site, so that the actual HTML form request is at some URI apart from the REST API.
Include the HTML form as part of the 'facts' URI response.
To clarify, I'm trying to follow true REST architecture as specified by Roy Fielding, not half-baked RPC posing as REST.
edit: I'm starting to think #3 is on to something.
edit2: I think a solution is to have regular non-REST HTML navigation in a CRUD manner, and then the frontend makes AJAX REST calls as appropriate (or the backend makes internal calls to its REST API).
The reason I need to do the REST part of this service correctly is that I want to allow other non-HTML clients to interact with it later on.
In my mind, the only cleanly RESTful answers are 1 and 3.
As I see it, the description of the resource is a resource of its own. The question is whether you want to make this resource accessible through your application's API or if you want to make it part of the API itself.
For 1, it seems RESTful make the URIs something like this:
GET /facts -> all facts
GET /facts/1 -> returns fact 1 (obviously the id might be a word or something else)
GET /facts/create -> returns a form appropriate for creating a fact
POST /facts -> adds a fact
I think you're overcomplicating things a bit. A web browser is just not a perfect REST client, so you can't have a perfectly RESTful solution. In a perfect world, you would not need a form at all, because the web browser would know your media types and build the form itself.
Meanwhile, I suggest you just use what most REST frameworks would call an additional "view" on the resource to return a form:
E.g. /your/collectionresource?view=form, or /your/collectionresource;form