Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put forms / alternative views in a RESTful html app?

Tags:

rest

html

forms

Let's assume an web application that for each URI presents a nice html view for GET requests and allows to update the underlying resource through POST/PUT/PATCH/WHATEVER.

How do I then expose various forms that actually allow performing such requests from the browser? And broader: assuming I have alternative views (possibly also HTML) for the same resource, where do I put those? Arguably, such forms can be considered alternative views, so having an answer to the broader question would be ideal.


Edit: To clarify, my question is not about pure data APIs serving JSON or whatnot, but about HTML apps such as Stackoverflow. For example you can get the collection of questions under /questions and this particular one at /questions/24696982 which makes sense. To get the form to add a new question, you will have to use /questions/ask, which I'm not sure is alright. And that form POSTs to /questions/ask/submit, which seems just plain wrong. Making a GET request to that URL yields a 404 (if anything it should be a 405). The form should be POSTing to /questions. Still I would like to know whether at least the URI for the form is considered acceptable in a RESTful system.

like image 429
back2dos Avatar asked Jul 11 '14 11:07

back2dos


4 Answers

You have a website like, the one way to build a real RESTFull API is to split the frontend and the API - thats in my opinion the best way (some may disagree) - maybe some other don't think like this but lets say the frontend team got www.domain and your team for the API got api.domain.

GET api.domain/questions - Retrieves a list of tickets   
GET api.domain/questions/12 - Retrieves a specific ticket   
POST api.domain/questions - Creates a new ticket  
PUT api.domain/questions/12 - Updates ticket #12  
DELETE api.domain/questions/12 - Deletes ticket #12  
PATCH api.domain/questions/12 - Partially updates ticket #12 #I only want to display that this also exists - i don't really use it...   

AWESOME EDIT: As you can see also stackoverflow uses this method: api.stackexchange.com

So as you can see you can have these structure - but you also can have a form on www.domain/questions/ask and this form would send the request to api.domain/questions via POST. I want to refer to: https://thenewcircle.com/s/post/1221/designing_a_beautiful_rest_json_api_video its a really nice podcast you should have heard.

EDIT: (another point of view)

Another idea is that you can simply choose which content should come back (Json,XML,HTML) if your client sends you the right Accept-Header.

Example 1:

       URL           REQUEST       ACCEPT HEADER               RESPONSE                      
-----------------------------------------------------------------------------------------
domain/questions      GET        application/json   all questions as json
domain/questions      GET        text/html          the page as html with all questions
domain/questions/ask  GET        text/html          Your html for to add a new question
domain/questions      POST       application/json   Add a new new questions (this would be called from ./ask to add the new questions
domain/questions/ask  GET        application/json   404 Status-Code because on questions/ask you don't have implemented any resource

Example-2:

       URL              REQUEST     ACCEPT HEADER               RESPONSE                      
-----------------------------------------------------------------------------------------
domain/questions/12       GET      application/json   Shows the questions with the ID 12 as JSON
domain/questions/12       GET      text/html          Shows the HTML representation of your page
domain/questions/12/edit  GET      text/html          Your html for to edit a the question
domain/questions/12       PUT      application/json   Updates the questions with the ID 12 // just to add the PATCH thing.. i don't really use it but if you don't update the whole object you could/should use PATCH instead of PUT :p
domain/questions/12/edit  GET      application/json   404 Status-Code because on questions/ask you don't have implemented any resource

Yesterday I told you about the first idea (which is - I think for using an api as a team (one for frontend and one team that develops the api - a better way) but as @jackweirdy commented (thanks for that - i then searched a lot and was looking at other podcasts from developer around the world and how they would do that) below it's really all up to you - it's your api and at the end you/your team will decide for one way. Hope this helps you or other that looking for how to build a API on a REST background.

The examples in the EDIT-Section would be (if I got it right) not like here on stackoverflow

like image 108
DominikAngerer Avatar answered Oct 30 '22 07:10

DominikAngerer


This is something I've had trouble with myself, and which I don't think there's a right answer to.

Assuming I have an API exposing /people/:id, I generally reserve an endpoint for /people/new. a GET request to that url with Accept: text/html will return a form for creation, but anything else will throw a 404, since this page only exists for people in a web browser. The form on that page will then post to /people/ as you'd expect.

Similarly, if someone wants to edit an existing person, the form to do that might be served from /people/1/update, again HTML only.

If your API has that structure, then I think reserving keywords such as new or update is perfectly reasonable.

like image 26
jackweirdy Avatar answered Oct 30 '22 09:10

jackweirdy


As far as I can understand your question, you want an application that :

  • displays HTML pages (and eventually other formats ?)
  • displays form views for creation of new elements or for update of existing ones
  • accept POST/PUT with url encoded data (sent by submitting above forms) to create of update those elements (and eventually other formats ?)

Ruby on Rails is a framework that is targetted as this kind of requirement. Extract from the guide Rails Routing from the Outside In :

HTTP Verb   Path            action      used for
GET        /photos          index       display a list of all photos
GET        /photos/new      new         return an HTML form for creating a new photo
POST       /photos          create      create a new photo
GET        /photos/:id      show        display a specific photo
GET        /photos/:id/edit edit        return an HTML form for editing a photo
PUT        /photos/:id      update      update a specific photo
DELETE     /photos/:id      destroy     delete a specific photo 

You can have HTML views for the actions index, new, show and edit.

Personally, I would recommend to add the following :

POST       /photos/:id        update    update a specific photo
POST       /photos/:id/delete destroy   delete a specific photo

so that it would be simpler to update or delete elements via html forms.

All those paths are only Rails convention and are not imposed by REST but it gives a clean example of what can be done.

But it is quite easy to make an application following the same or slightly different conventions using other frameworks. Java + Spring MVC can do that very easily, with HTML views using JSP, Velocity, Thymeleaf or others, and the possibility of using JSON in input or output simply using HTTP headers or suffixes in URL (GET /photos/:id.json) with a little less magic but more control than RoR. And I'm not an expert in other framework like Struts2 (still Java), or Django (Python) but I am pretty sure that it is possible too.

What is important :

  • choose a language (Ruby, Python, Java, PHP, ASP.NET, ...)
  • choose a framework compatible with RESTfull urls
  • ensure you can have views in HTML, or JSON, or enter the format you want by adding a suffix or a HTTP header and eventually the appropriate adapter/converter

You could do it by hand but frameworks limits boiler plate code.

like image 33
Serge Ballesta Avatar answered Oct 30 '22 09:10

Serge Ballesta


You need to understand that there is a difference between a RESTfull application and a REST client.

A RESTfull application has pure restfull urls as you described, such as

GET     /persons   : gets a list of all the persons in database
POST    /persons   : adds a new person
GET     /person/1  : gets a person with id 1
PUT     /person/1  : updates person with id 1
DELETE  /person/1  : deletes person with id 1

and so on...

Such an application does not have any forms or UI for submitting data. It only accepts data via HTTP requests. To use such an application you can send and receive data using tools like curl or even your browser, which allow you to make HTTP requests.

Now, clearly such an application is not usable from the user point of view. Hence we need to create client applications which consume these restfull applications. These clients are not restfull at all and have urls like:

GET     /person/showall  : displays a list of all persons
GET     /person/create   : shows new person form
POST    /person/create   : submits the data to the restfull application via ajax or simillar technology.

and so on...

These clients can be another HTML application, an android application, an iOS application, etc.

What you are trying to do here is create a single application which has both restful urls for objects as well as forms/pages for data display and input. This is absolutely fine.

Just make sure that you design proper restfull urls for your objects while you can have any url you find suitable for your forms.

like image 28
Dhruv Chaudhary Avatar answered Oct 30 '22 07:10

Dhruv Chaudhary