Whats the REST way of showing forms to user - html

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.

Related

Embed formated ACL information to JSON in Symfony2

I am using Symfony2 and its ACL security component in my project. I want to use the ACL information in the frontend framework for show/hide elements.
Would it be a terrible idea security wise to attach formated ACL information for current user on current object?
Lets say the user has permission to VIEW and EDIT object, so the JSON data would look like this:
{
"id": 1,
"name": "Product",
"_permissions": ["VIEW", "EDIT"]
}
What security holes this solution can potentially cause?
I don't think there is a security problem. You will agree that it can not be a problem to have the id and type of the object in your data :-). So the only thing we should take a look at are the VIEW and EDIT attributes. These values are not a secret. They are part of the Symfony documentation. So it's only about the information if you have these permissions for that object.
If you return that JSON together with your data I think, the VIEW attribute is actually no additional information as it would not be returned if you would not have the VIEW permission. So the only information you provide here is if the user can edit that object.
If you think about it you will agree that you would provide the same information if you would on server side decide based on permissions if you add an edit link for that object to a html page or not.
So if you do an isGranted("EDIT", $product) to decide if you return that EDIT as part of your JSON I can not see any security hole there.

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.)

Implementing the REST Hypermedia Constraint with a two backend services

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).

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

HTML interface to RESTful web service *without* javascript

Even if I offer alternatives to PUT and DELETE (c.f. "Low REST"), how can I provide user-friendly form validation for users who access my web service from the browser, while still exposing RESTful URIs? The form validation problem (described below) is my current quandry, but the broader question I want to ask is: if I go down the path of trying to provide both a RESTful public interface and a non-javascript HTML interface, is it going to make life easier or harder? Do they play together at all?
In theory, it should be merely a matter of varying the output format. A machine can query the URL "/people", and get a list of people in XML. A human user can point their browser at the same URL, and get a pretty HTML response instead. (I'm using the URL examples from the microformats wiki, which seem fairly reasonable).
Creating a new person resource is done with a POST request to the "/people" URL. To achieve this, the human user can first visit "/people/new", which returns a static HTML form for creating the resource. The form has method=POST and action="/people". That will work fine if the user's input is valid, but what if we do validation on the server side and discover an error? The friendly thing would be to return the form, populated with the data the user just entered, plus an error message so that they can fix the problem and resubmit. But we can't return that output directly from a POST to "/people" or it breaks our URL system, and if we redirect the user back to the "/people/new" form then there is no way to report the error and repopulate the form (unless we store the data to session state, which would be even less RESTful).
With javascript, things would be much easier. Just do the POST in the background, and if it fails then display the error at the top of the form. But I want the app to degrade gracefully when javascript support isn't available. At the moment, I'm led to conclude that a non-trivial web app cannot implement an HTML interface without javascript, and use a conventional RESTful URL scheme (such as that described on the microformats wiki). If I'm wrong, please tell me so!
Related questions on Stack Overflow (neither of which deal with form validation):
How to send HTML form RESTfully?
How do you implement resource "edit" forms in a RESTful way?
you could have the html form post directly to /people/new. If the validation fails, rerender the edit form with the appropriate information. If it succeeds, forward the user to the new URL. This would be consistent with the REST architecture as I understand it.
I saw you comment to Monis Iqbal, and I have to admit I don't know what you mean by "non-RESTful URLS". The only thing the REST architecture asks from a URL is that it be opaque, and that it be uniquely paired to a resource. REST doesn't care what it looks like, what's in it, how slashes or used, how many are used, or anything like that. The visible design of the URL is up to you and REST has no bearing.
Thanks for the responses. They have freed my mind a bit, and so in response to my own question I would like to propose an alternative set of RESTful URL conventions which actually embrace the two methods (GET and POST) of the non-AJAX world, instead of trying to work around them.
Edit: As commenters have pointed out, these "conventions" should not be part of the RESTful API itself. On the other hand, internal conventions are useful because they make the server-side implementation more consistent and hence easier for developers to understand and maintain. RESTful clients, however, should treat the URLs as opaque, and always obtain them as hyperlinks, never by constructing URLs themselves.
GET /people
return a list of all records
GET /people/new
return a form for adding a new record
POST /people/new
create a new record
(for an HTML client, return the form again if the input is invalid, otherwise redirect to the new resource)
GET /people/1
return the first record
GET /people/1/edit
return a form for editing the first record
POST /people/1/edit
update the first record
GET /people/1/delete
return a form for deleting the record
(may be simply a confirmation - are you sure you want to delete?)
POST /people/1/delete
delete the record
There is a pattern here: GET on a resource, e.g. "/people/1", returns the record itself. GET on resource+operation returns an HTML form, e.g. "/people/1/edit". POST on resource+operation actually executes the operation.
Perhaps this is not quite so elegant as using additional HTTP verbs (PUT and DELETE), but these URLs should work well with vanilla HTML forms. They should also be pretty self-explanatory to a human user...I'm a believer in the idea that "the URL is part of the UI" for users accessing the web server via a browser.
P.S. Let me explain how I would do the deletes. The "/people/1" view will have a link to "/people/1/delete", with an onclick javascript handler. With javascript enabled, the click is intercepted and a confirmation box presented to the user. If they confirm the delete, a POST is sent, deleting the record immediately. But if javascript is disabled, clicking the link will instead send a GET request, which returns a delete confirmation form from the server, and that form sends the POST to perform the delete. Thus, javascript improves the user experience (faster response), but without it the website degrades gracefully.
Why do you want to create a second "API" using XML?
Your HTML contains the data your user needs to see. HTML is relatively easy to parse. The class attribute can be used to add semantics as microformats do. Your HTML contains forms and links to be able to access all of the functionality of your application.
Why would you create another interface that delivers completely semantic free application/xml that will likely contain no hypermedia links so that you now have to hard code urls into your client, creating nasty coupling?
If you can get your application working using HTML in a web browser without needing to store session state, then you already have a RESTful API. Don't kill yourself trying to design a bunch of URLs that corresponds to someone's idea of a standard.
Here is a quote from Roy Fielding,
A REST API must not define fixed
resource names or hierarchies
I know this flies in the face of probably almost every example of REST that you have seen but that is because they are all wrong. I know I am starting to sound like a religious zealot, but it kills me to see people struggling to design RESTful API's when they are starting off on completely the wrong foot.
Listen to Breton when he says "REST doesn't care what [the url] looks like" and #Wahnfrieden will be along soon to tell you the same thing. That microformats page is horrible advice for someone trying to do REST. I'm not saying it is horrible advice for someone creating some other kind of HTTP API, just not a RESTful one.
Why not use AJAX to do the work on the client side and if javascript is disabled then design the html so that the conventional POST would work.