Understanding REST conceptually with Rails - ruby-on-rails

I'm a little late to the party, but I'm trying to wrap my brain around how REST is supposed to work, both in general and in Ruby on Rails. I've read a bunch of articles online about this already, but still don't feel like I'm getting the big picture.
REST as I understand it, is a series of aspirational statements, with the net result at the bottom being that URLs should contain all the information necessary to handle a request, and gets should not be able to change the state on the server, and a bunch of other concrete guidelines.
As I understand it, REST in Rails is based around CRUD, which is to say, every model has a create, read, update and a delete action. Each of these actions is accessed through a similar set of URLs, generated by mapping a resource in the routes. So a login URL is creating a user session, so the URL would look like example.com/session/new with a POST, and logout would be example.com/session/destroy with a POST.
What exactly is the benefit of standardizing URLs in this fashion? It strikes me as optimizing for machine readability at the expense of human readability. I know that you could then remap in the routes file example.com/login to example.com/session/new but that is just one more step for no apparent gain to me.
Is it considered really bad practice to develop a website that uses traditional routes now?
Furthermore, each of these CRUD actions should be able to respond to requests with whatever type of response the request is looking for. So the same link to, say, example.com/tasks could also be called at example.com/tasks.xml to get an xml representation of the result, or example.com/tasks.json for a json representation.
Is this to say that a RESTful API would just be the usual links on the site but with xml appended? It strikes me as very strange and awkward that a web API would behave in this way, but this seems to be what's implied by everything I've read. I'm more used to seeing an API that has links like example.com/api/tasks to get the list of tasks. What exactly is the advantage of this approach?

Rest provides another chunk of "convention over configuration." For a widely used, limited set of common problems (crud actions against the models as a whole), rest is very useful as an application development convention.
What exactly is the benefit of
standardizing URLs in this fashion?
Programmer efficiency. Less to think about; enables more time to be spent on harder problems, etc. Better maintainability. Easier testing. Etc.
Is it considered really bad practice
to develop a website that uses
traditional routes now?
Yes, for crud actions that are interacting with an entire record of the model.
Furthermore, each of these CRUD
actions should be able to respond to
requests with whatever type of
response the request is looking for.
So the same link to, say,
example.com/tasks could also be called
at example.com/tasks.xml to get an xml
representation of the result, or
example.com/tasks.json for a json
representation.
Is this to say that a RESTful API
would just be the usual links on the
site but with xml appended?
Yes, if your api fits the rest model. I think the big issue is authentication. If you want your api to be stateless, then you'll probably need to include authentication with each call. At that point, if you don't want to use HTTP level authentication, you'd need to decide how to include the credentials.

Related

Integrating Rails APIs with Forms

I've read quite a few articles on good design for Rails APIs. However, I can't seem to find what I'm trying to do. And it's different enough that I'm not sure what to do.
So this Rails site has forms for generating various records for my various tables. It all works fine. No problem there. This is all admin-level stuff.
However, a few of these forms need to be also be available as an API. Right now my APIs work fine but it's poor design (I think). Currently the user will make an API request to do some action and pass some information in (i.e. add record to Foo).
My method inside the API, special_new_foo, more or less duplicates my create inside the foo controller that a form would route to. Is there a way I can reuse my standard create method? The API would then just check for good data, etc. and pass the information onto the controller...
I was thinking about just making an HTTP request to the local server on the machine (which is basically how the forms work, except they're two separate machines). Is this good practice?
Thanks!
One option is to allow you controller to respond with different formats, depending on the request. I think this is what rails generates on scaffolding. However i barely saw any real world app doing this. See also my answer to Is it necessary to build a separate API endpoint for mobile apps to access a Rails web app?
A better solution is to make an extra ServiceObject or FormObject dealing with business logic of your controllers and reuse this object in both endpoints
see http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

RESTful websites vs. RESTful APIs - What's the difference and does it matter?

I've been reading a lot about REST and how to do REST the "right way". Most resources use terms like RESTful web services or RESTful APIs, however none mention RESTful websites. I am confused by this given that I think of a website and an API as two different things. Yet, when, for example, designing a website using the Rails framework, you're constantly reminded about how RESTful everything is (or is supposed to be).
I get the fact that REST provides a lot of advantages (its architectural properties) for APIs (e.g. a JSON API), but I just don't see how a website benefits from being RESTful. As a simple example consider login functionality. In a REST fashion this can be modeled by making a Session model with logging in corresponding to creating a new sesssion, logging out destroying a session and so on. The URLs would look something like this:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/login(.:format) sessions#new
user_session POST /users/login(.:format) sessions#create
destroy_user_session DELETE /users/sign_out(.:format) sessions#destroy
However, these URLs are not very user friendly. From a users point of view it makes more sense to just have a /login path where the login form is displayed. It is also easier to remember. But if we make the URLs map like that they're not really (as) RESTful anymore; does /login identify a resource. If so which one?
Another example is the home page /home or just /. How does that fit into REST? On most websites the home page is a mashup of many different kinds of information and doesn't identify any single resource. For example it could be a page that lists the newest products in a catalog and the last date you logged in; two completely unrelated things. How is that RESTful?
I understand why having a RESTful API separate from a website makes sense, but my confusion lies with how REST applies to websites - if it even does.
The short answer is that no one talks about RESTful websites because websites are RESTful by default. You really have to try to make a non-RESTful website (though it has been done--see below).
The setup you're describing takes a lot of elements from REST, but it's not "REST" per se: it's a set of conventions designed for the convenience of server-side programmers. Most of today's web APIs only use a subset of the REST constraints, and it's a subset that doesn't include the main driving principle behind websites.
Let me back up a bit. Here's what websites and web APIs have in common: they both expose functionality through resources. Each resource is identified by a URL, and each responds to an appropriate subset of the standard HTTP methods. (This may seem obvious, but look at XML-RPC or SOAP, where there's only one URL for the whole system.) A resource might send documents to the client (in response to a GET request) and/or it might accept documents from the client (along with a POST or PUT request).
Now, the differences. Web APIs often map the four most common HTTP methods (POST, GET, PUT, DELETE) onto the four CRUD operations (Create, Read, Update, Delete). Web sites can't do this, because web sites run on HTML, and HTML forms only support two methods: GET and POST. And yet, a web site can easily describe all sorts of actions--"search", "next page", "purchase", "unfriend"--which are nontrivial to map onto CRUD.
That's because HTML supports links and forms. This is what's missing from the "Web API" branch of the family tree. Not the resources, but the machine-readable connections between resources. (To drop some REST jargon, this is "the hypermedia constraint" or "hypermedia as the engine of application state.")
"Web APIs" tend to ignore the hypermedia constraint because a) it's difficult to understand, and b) JSON doesn't support links or forms, so it's difficult to obey the hypermedia constraint even if you want to. (This is changing with the development of formats like JSON-LD, Hydra, and HAL.)
But the hypermedia constraint is literally what holds the Web together. Take away the links and the forms, and you'd be left with an unusable mess.
Python Challenge is a good example of a non-RESTful website. You get a starting URL and then you have to solve a little puzzle to figure out how to get to the next URL in the sequence. You still have resources, and each resource has a URL. But the connections between resources are obscured. This is fun as a game, but no one would run a serious website this way. Unfortunately, this is kind of where we are in terms of "Web APIs."
Further reading
As you can tell, this is a complex topic. At the risk of tooting my own horn, the "maturity model" I developed for a 2008 talk might help you understand the architectural difference between the World Wide Web (level 3) and most of today's APIs (level 2). I'd also recommend Steve Klabnik's Designing Hypermedia APIs, and my own RESTful Web APIs, which starts out by comparing a web API to a website that does exactly the same thing.
My earlier book, RESTful Web Services, also covers this topic, and it's free to read online. However, it's somewhat out of date (it was published in 2007), and in retrospect I don't think it pushes the hypermedia angle hard enough.
Miscellaneous
To briefly respond to a couple of minor points from your original question:
There is no technical difference between a web API and a website. A website is a web API that happens to serve HTML documents.
One URL is not more "RESTful" than another. This is solely a usability issue. On a technical level it doesn't matter at all what your URLs look like. /users/login.json and /login and /the-first-100-prime-numbers.gif are all equally RESTful ways to refer to a login form.
The home page is a resource: it's a "home page" resource. Its job is to contain the most important bits of information, and to guide the client to other pages--either directly through links, or indirectly through a search form. A resource does not necessarily correspond to a row in a database or an object in an object model. A resource can be absolutely anything, even a real-world object or an abstract concept. The only restriction is that a resource must have a URL.
/login is a URL, so yes, it identifies a resource. What kind of resource? If it's a typical scenario where sending "GET /login" gets you an HTML page with a login form, then it's a "login form" resource. If filling out the login form triggers a "POST /login" request, then it also acts a "login form processor" resource.
You might have better luck thinking of a resource in terms of the code that runs when a request for its URL comes in, rather than trying to map it to one particular "thing" in your dataset. That is, instead of trying to figure out what a resource is, think of it in terms of what it does.
Hope this helps.

Which simple REST URL pattern is more common / better?

/controller/action/id
or
/controller/id/action
Which is more common? Which is preferable and why?
Are there any pro's / con's of using one or the other?
Edit:
Or, perhaps to think of this question in a different way, why do most MVC frameworks (ASP.Net MVC, Grails, Spring MVC) default to the /controller/action/id URL pattern? Is there some advantage to this?
Neither of these are RESTful. There should not be verbs/actions in a URL. Those are confined to the HTTP method for good reason (so that clients can interact with your service without knowing anything specific about it).
If you can not do anything except GET and POST, use POST to send an action parameter to /controller/id
Asp.Net MVC uses /controller/action/id. So that is what you'll most often see in that environment. I do not see any technical benefits but simply going with a common pattern can make things easier to understand.
I definitely prefer /controller/action/id. This feels to me more like it is identifying a resource (a noun) rather than identifying an action on that noun (a verb).
In addition to the exact URL to the resource, you need to consider how you are mapping the HTTP verbs. In my experience, we have shuffled the URL around based on what made most sense when combined with the verbs. That said, we also have a couple places we broke the canonical approach for convenience sake (for example, exposing a certain delete action with a GET so that users could perform the action via a browser).
Also take a look at this discussion for more.
REST URL structure advice

RESTful design, how to name pages outside CRUD et al?

I'm working on a site that has quite a few pages that fall outside my limited understanding of RESTful design, which is essentially:
Create, Read, Update, Delete, Show, List
Here's the question: what is a good system for labeling actions/routes when a page doesn't neatly fall into CRUD/show/list? Some of my pages have info about multiple tables at once. I am building a site that gives some customers a 'home base' after they log on. It does NOT give them any information about themselves so it shouldn't be, for example, /customers/show/1. It does have information about companies, but there are other pages on the site that do that differently. What do you do when you have these situations? This 'home-base' is shown to customers and it mainly has info about companies (but not uniquely so).
Second case: I have a table called 'Matchings' in between customers and companies. These matchings are accessed in completely different ways on different parts of the site (different layouts, different CSS sheets, different types of users accessing them, etc. They can't ALL be matchings/show. What's the best way to label the others?
Thanks very much. =)
I'm certainly no expert, but if you rethink your resources and think of them more strictly as 'nouns' or at least lists of data, it might be easier to fit any desired action into GET, POST, PUT, and DELETE. For example, you have a /customers/ resource could presumable have a /customers/{username}/ resource for each customer. Maybe that gives them information about themselves. You could have /homebases/{username}/ or /customers/{username}/homebase/ as your homebase resources. Presumably, you'd access that homebase resource mainly through GET, and POST if there's anything there to update (which I wouldn't expect on a home-base or dashboard since it's an aggregate resource).
For 'matchings' you could use something like /matchings/{customer},{company}/ (yes, commas and semicolons are allowed. Commas usually mean the two parts are order-dependent and semicolon means order-independent, though there's no rules about it). From that resource, you can have GET to read, show, and list whatever data you need (including optional query parameters passed as the body of the GET request), POST to update, PUT to create, and DELETE to delete. Using the parameters passed in GET, you could also request different views of the same data. Of course, you can have sub-resources of that matching like /matchings/{customer},{company}/invoices/{invoice#}/.
I liked the book "RESTful Web Services" (2007 O'Reilly), by the way.
I hope that makes some sense and is helpful. =)
Aggregate and composite views are a serious problem, I think. I had to deal with the homepage problem that went against everything RESTful I knew.
My solution was to consider the homepage or dashboard as a resource in itself, but a resource where only GET operations made sense. POST/PUT/DELETE from the homepage were directed to the specific resources as usual.
Matchings, in contrast, seems an easier problem to tame. It seems like a simple mapping between Customers and Companies from your description, and you could parametrize it based on querystring parameters.
/matchings?companies=X,Y,Z&locations=NY,CA,TX
By RESTful design, I assume you mean RESTful web services, since a REST-based architecture has a much broader sense than that.
The main thing to consider is that REST-based architectures rely on the HTTP protocol, in virtually all cases. Since HTTP specifies a set of methods, sometimes these methods are used to create the so called RESTful web services.
But the RESTful web services don't follow any concrete standard (unlike SOAP). It is common to use:
GET - for fetching existent items
POST - for creating new items
PUT - for updating existent items
DELETE - for removing existent items
Create, Read, Update and Delete (CRUD) are the basic functions of any persistent storage.
It is easy to see that in common RESTful web services, each HTTP method is being used to match one of the basic functions, but the point is: it doesn't have to be this way.
There are other things to consider, URL mapping is one of them (as this is the concern of your question), security is another. POST requests send the content of the request in the HTTP body (which can be encrypted), but GET requests send it in the URL, visible for everyone to see.
If one wants to develop a secure (encrypted) RESTful web service, one could make all requests HTTPS POST, and then specify within the request, which of the CRUD operations one wants to perform, and on what resources.
One could also expand the CRUD concept to a wider range, in fact, in almost every application, one has to.
Remember CRUD are just the four basic operations in which all other actions can build upon. There's no standard you have to follow, you can specify your own protocol, according to what makes sense in your context, and keeping all the relevant considerations in mind (security, URLs, etc.)
Specifically regarding your question, you can have your own actions, like show_by_x, show_by_y, etc. The REST police is not coming to arrest you :-)
REST and ORM is 2 different things, because of that even though you have a model called User , you done necessary to have a users resource. Resources should be managed in the rails controller level
Think resources as modules/sections
Ex: you might want your users to land on a dashboard page after they log in (and say you have two categories of users Administrators and normal users), so you can have two resources namly
admin_dashboard
uer_dashboard
and both might only have read action
Second case :
consider having something like above example (different resources according to different user levels) if possible
I'm not a REST guru, but hope this helps :D
cheers,
sameera

What are the benefits of enforcing restful routes in an MVC application?

I've been toying with the SimplyRestfulRouting assembly that comes with the MvcContrib extras, and for the most part I really like that it quickly sets up my routes and leaves me with a good convention to follow in my controllers. However, I'm still trying to wrap my head around REST as it applies to rich internet applications and occasionally feel pigeon holed when I need to do something that falls outside the scope of those 8 or 9 default routes. [Edit: By "pigeon holed", I simply mean I feel like I'm dirtying up the application when I have to create a controller action that is outside the definition of the default "restful routes".]
I heard a comment from a REST proponent in which he stated his opinion that the MVC framework is inherently RESTful, and it got me thinking a bit more about what libraries like the MvcContrib SimplyRestfulRouting are actually buying me.
Not having read a lot about the concrete pricinples of REST, I'm looking for input as to what benefits might come from enforcing such a thing in the context of a forms-over-data, RIA. And with regards to AJAX, how does a RESTful architecture affect my client interaction?
It's likely I'm misunderstanding the use of REST in this context, and would appreciate some StackOverflow mojo to get my head on straight.
The main benefit I can see in enforcing RESTful routes -- regardless of the framework used -- is consistency. You'll always be able to know how the API will work for any resource, which will in effect give you a self-documenting API.
It also provides a wonderful constraint while architecting the application. Rather than having an API with a blank slate that could get complicated very quickly, constraining the routes to the basics will give you guidance as to which resources you'll need to create.
For more of the basic principles surrounding REST, I'd recommend reading this thread.
Being RESTful is more than just having clean URLs.
At an architectural level, REST is about organizing your application functionality in terms of resources, and exposing a fixed and uniform set of CRUD operations on them (e.g. HTTP POST/GET/PUT/DELETE methods). This is known as Resource Oriented Architecture.
In contrast, with Service Oriented Architecture you typically organize application functionality in terms of processes or components, and expose non-uniform, application specific methods on them (e.g. via SOAP).
Note, you can have clean URLs but still end up following non-RESTful SOA design principles.
UPDATE: Sorry, didn't really answer the question, got hung up on use of "RESTful" terminology. If you're just talking about the benefits of clean URLs (REST/SOA argument aside), the typical argument is better SEO optimization and user-friendliness (user can better make sense of and modify URLs).
the advantage is that if you have some adress and from that adress you getting something, then you can call that adress from anywhere you want in you code, and you will get exactly same thing :)
and in concrete example, if you have route that can return some html full with data(user control for example), then you can call it from ajax, from your desktop application or even from your web service...it is very powerfull because you WILL have some functionality repeated over your application...and because some html that you getting from that restful service giving you exactly one view with exactly one functionality, you can call it dynamically from dialog or from page or from your desktop application or from anywhere...
and when you add to this that you can call this adress with parameters, exactly like some method, you can now see how powerfull this can be in creating dynamic pages and web sites/systems
hope this helps

Resources