How to name RESTFUL resources in this case - ruby-on-rails

I am developing a petitions site that is using RESTFul techniques.
For example: /petition/1 indentifies a certain petiton (resource).
How should I name
a) Signing a petition?
/petition/sign/1
or
/petition/1/sign
or
???
b) Searching for a petition based on terms (rich, for example)
/petition/search/rich
/petition?search=rich
And lastly
c) Seeing only a certain category
/petition/category/1
/petition?category=1
Thank you.

As #BrianDriscoll mentioned in his comment, when creating the URLs for resources in a REST architecture, you have to be careful to keep the URLs to being just the nouns (the things in your application) and the verbs are the HTTP methods.
Now that that little bit is out of the way, we can start to dig in to what the nouns in your application really are. From the looks of it, you have essentially 3 "things" (or nouns) in your domain:
Petitions
Petition Signatures
Petition Categories
Assuming that a Petition Signature can only ever be applied to one petition, I would expect the following URL patterns to represent your resources:
/petitions - A list of all petitions (the petition root)
/petitions/5 - A single petition
/petitions/5/signatures - A list of all signatures for a single petition
/petitions/5/signatures/7 - A single signature on a single petition
/categories - A list of all the categories (the category root)
/categories/3 - A single category (which is probably a list of all petitions in the category)
Then, with these resources, you can use the HTTP verbs to manipulate the resources:
POST /petitions - Create a new petition
POST /petitions/9/signatures - Create a new signature on the petition
etc.
Lastly, for searching, you would simply pass a query string to your /petititions URL like so:
GET /petitions?query=blah
The query can be whatever you need for the search engine and it should return a list of petitions that match that query. The same holds true for searching on signatures within a petition or petitions within a category.
This should be enough to get you up and running for now. Ultimately, it comes down to deciding on what "things" and representations of those things your application needs, and then the URLs are just the "names" of those things, much like an address is the "name" of a house. Interacting with those resources (things) is done through the different HTTP verbs.
This is only scratching the surface of the true power of a REST architecture, which includes things like defining content types so that clients know how to navigate your domain, and using hypertext as the engine of application state so that clients can actually do the navigation on a server.

I would do
POST to /petitions/1/signatures
GET to /petitions?query=rich
GET to /categories/1/petitions (assuming you want a list of petitions in a category)
For rails routes it would be:
resources :categories do
resources :petitions
end
resources :petitions do
resources :signatures
end

Related

rails, implementing a master detail yet staying RESTful

Say that I have a Customers and an Orders tables, where each Customer may have many Orders.
Since in rails we are encouraged to represent these resources in a RESTful style, each of our resources, will respond to the following actions
index
show
edit
new
create
delete
So far, it all is very fair and plain. But now say that each time i open the show page of my Customer, i want to show a detail table containing all his/her orders.
This is a very common need, but doesn't this "unclean" the correctness of restful approach?
Is there some workaround, like "mashing" the two resources at a "view level", leaving them separate from the rest point of view?
Rails' default conventions ensure a RESTful application, and the only way this might become non-restful would be if you used custom-names on the routes, in which case you would have you add an extra bit of code to specify the HTTP method.
So, to accomplish what you're suggesting, at the view level, you may have something like this:
app/views/customers/show.html.erb
....
<% if customer.orders.any? %> #the orders method is provided on `customer` by defining the `has_many` and `belong_to` associations
<%= render #orders $>
And you would make sure to define #orders in the show action of the customers_controller.rb file.
This not only is RESTful, but also works within Rails' default conventions.
Those actions you list are not what makes something RESTful. There are a bunch of characteristics an application must have to be considered RESTful. Some of these characteristics are:
it is thought of as a repository of resources
resources are identified by a URI
there is a uniform interface for interacting with resources - the HTTP verbs of GET, POST, PUT, DELETE, etc.
Rails takes care of receiving HTTP requests and calling your application's functionality, regardless of whether it is RESTful in nature or not, through routing. Rails routing takes those HTTP verbs I mentioned, in combination with a URI, and determines which controller to call. By default Rails follows the RESTful paradigm, and by convention will map verb/URI combinations to those actions you listed - but the actions themselves, and the fact that they are lumped into a single controller, are not part of REST - they are just the rails convention.
In fact, the rails default routing maps 4 different resources to that single controller and its actions:
/customers // the list of all customers, GET/POST -> index/create
/customers/new // a form for creating a customer, GET -> new
/customers/{id} // a single customer, GET/PUT/DELETE -> show/update/destroy
/customers/{id}/edit // a form for editing a customer, GET -> edit
Resources can contain sub-resources, and Rails completely supports that. A sub-resource might be:
/customers/{id}/orders // the list of all orders for a particular customer
Another key part of REST is that it supports a resource having different representations, whether that is HTML, XML, JSON, etc. Clients use HTTP headers to convey what representation they are passing into the app (using the Content-Type header) and (usually) what they will accept in response (using the Accept header).
Its up to the application to determine what a resource representation looks like. Typically a resource will either be "thin" or "fat". A "thin" resource is one that simply has links to its sub-resources and further calls must be made to get them. A "fat" resource will contain the fully-fleshed out sub-resources it contains. Typically with an HTML representation, an application will return some form of "fat" resource. There is nothing non-RESTful about this - and is exactly what you are describing you want for your application.
So that was my long way of saying "don't be afraid of not being RESTful by displaying sub-resources - it's perfectly OK" :-)

Restful URI from Rails Tutorial Demo app

From the originall rail tutorial: http://ruby.railstutorial.org/chapters/a-demo-app#sec-a_user_tour
URIs designed as followings
/microposts
/microposts/1
Now consider if you want to organize each micropost into exactly ONE categorie (name is unique), what URI you will perfer?
/categories
/categories/123
/categories/jewelries
/categories/123/jewelries
/categories/jewelries/123
or singular counterparts
/categories
/categories/123
/categories/jewelry
/categories/123/jewelry
/categories/jewelry/123
Naming ReST resources is mostly a matter of taste. Just keep them coherent. If you choose to name /categories to serve a list of category, choose /jewelries to serve a list of jewelry.
I prefer using singular, /category for a list of category, /category/123 for one category. You can use singular or plural as long as every resource follow the same rule.

What is a "resource" in Rails?

Dumb question but I have some lingering confusion of what, exactly, a "resource" is in Rails. The term is used everywhere but I get a funny feeling it might be being used rather loosely. It's referenced in the model, the controller and, quite literally, in routes.rb.
Is it the specific route? For example, map.resources maps the 7 RESTful "resources". So an example of one resource would be the call to, say, the index action of a particular class's controller?!?
Is it a reference to the whole page/object being retrieved? or perhaps, more narrowly, a database table? or the row being retreived?
Is it something else?
Anyway, hopefully someone can set me straight...
Any object that you want users to be able to access via URI and perform CRUD (or some subset thereof) operations on can be thought of as a resource. In the Rails sense, it is generally a database table which is represented by a model, and acted on through a controller.
For example, you might have a User resource (with a users table in your DB). This is represented by a User model, is mapped to users_controller with map.resources :users (which then generates routes like /users (a collection of User resources) and /users/1 (a specific User resource).
You act upon those resources by using the appropriate HTTP method when making calls to those resources. POST to the resource collection (/users) creates a new record; GET retrieves a list of resources (/users) or a specific user (/users/1). PUT updates a specific user (/users/1/), and DELETE destroys that user. The URLs are the same, but the result (and controller action) may be different based on the HTTP verb. The idea, though is that /users/1 always means "I'm interacting with the User that has ID #1", regardless of the action.
Here's a good article discussing how most developers think that "Resource" is synonomous with the database table, the argument, I guess, being that mapping to the resource is mapping the controller to that database table (or, with ActiveResource, to another REST url).
Basically, I think a "resource" is "persisted data." map.resources maps the 7 RESTful actions to a particular suite of persisted data.
But I haven't thought about it too much in depth. Good question!
I think they probably mean it in the general web sense, i.e., Resource (Web):
the referent of any Uniform Resource Identifier
I don't think it has anything to do with database tables.
open your model folder, that is a hint of what resources you have!
example: users, pictures, comments...
A lot of people here say that resources refer to the database tables you have. It might be true sometimes but not necessarily true always. I could give you a lot of examples where you don't have a corresponding table in your database for a particular resource. Hence asssociating it with tables is rather wrong.
I would define a resource as a route which maps to related requests. So instead of declaring separate routes for the actions you want to do you can simply declare them using a resourceful route.In Rails, a resourceful route provides a mapping between HTTP requests and URLs to controller actions.
So say you define resources :users in config/routes.rb. You can now use a number of helpers to the controllers in your application like edit_user_path which returns users/edit .
Here's a good link: https://api.rubyonrails.org/v5.2.1/classes/ActionDispatch/Routing/Mapper/Resources.html
Which basically says: Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your index, show, new, edit, create, update and destroy actions, a resourceful route declares them in a single line of code:
resources :photos

In Ruby on Rails, what does "resource" mean?

I see the word resource in many different places like: resource Routing, resourceful controller, and resources: photos. What does resource actually mean?
One more question: What does RESTful route mean?
That's a big question!
I'd start here to better understand what 'resource' or 'resources' does as it relates to routing: http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
The short of it is that that it formalizes a set of actions (for a specific controller) invoked by URL/HTTP Verb pairs that are responsible for modifying the state of a given resource. Think of resources as nouns: Order, LineItem, Offer and think about what you might want to do with those nouns: typically create them, delete them, modify them, retrieve some set of them, etc. As such, resources are often (but certainly don't have to be) your core model objects and/or some composite representation of those core models.
Again - the Rails Guides summarize what resourceful routes Rails very succinctly in Section 2.1 of the above link: 'In Rails, a resourceful route provides a mapping between HTTP verbs and URLs and controller actions'
If you're unfamiliar with REST, Wikipedia has some decent - but not exhaustive - coverage on the architecture: http://en.wikipedia.org/wiki/Representational_State_Transfer.

Ruby on Rails - differentiating plural vs singular resource in a REST API

I'm working on building the URLs for my REST API before I begin writing any code. Rails REST magic is fantastic, but I'm slightly bothered the formatting of a URL such as:
http://myproject/projects/5
where Project is my resource and 5 is the project_id. I think if a user is looking to retrieve all of their projects, then a respective HTTP GET http://myproject/projects makes sense. However if they're looking to retrieve information on a singular resource, such as a project, then it makes sense to have http://myproject/project/5 vs http://myproject/projects/5. Is it best to avoid this headache, or do some of you share a similar concern and even better - have a working solution?
Rails (3) has a lot of conventions when it comes to singular vs plural. For example, model classes are always singular (Person), while the corresponding tables are always plural (people). (For example, Person.all maps to select * from people.)
For routes, there's a concept of a singular resource as well as a plural resource. So if you did resource :account then you would get paths like /account for the default path or /account/edit for a path to a form to edit the account. (Note that Rails uses /account with a PUT method to actually update the account. /account/edit is a form to edit the account, which is a separate resource from the account itself.) If you did resources :people, however, then you would get paths like /people, /people/1, and /people/1/edit. The paths themselves indicate whether there can only be one instance of a given type of resource, or whether there can be multiple instances distinguished by some type of identifier.
I agree, go with the flow. Consider how the URL forms a hierarchy.
The root of your website is where you start to access anything.
/projects/ narrows it down to only projects, not anything else. From projects you can do lots of things, /list, /index/, /export, etc... the /id limits things even further.
At each / the scope of what do becomes narrower, and I think it makes sense.
Further programming is all about arbitrary rules. Indexs starting at 1 vs 0, and so on. Anyone working with your urls will sort things out in short order.
There are cases where a singular path to a resource is helpful. If your resource ids are non-numeric user defined names then routing clashes are possible. Example:
/applications/new --> create a new application or show user's application named new?
In this situation you can choose to limit the user input to avoid the clash, or, this can be worked around by overwriting the default Rails 3 behavior:
class ActionDispatch::Routing::Mapper
module Resources
RESOURCE_OPTIONS << :singular_resource
class Resource
def member_scope
#options[:singular_resource] ? "#{singular}/:id" : "#{path}/:id"
end
def nested_scope
#options[:singular_resource] ? "#{singular}/:#{singular}_id" : "#{path}/:#{singular}_id"
end
end
end
end
Then when specifying a new resource route:
resources :applications, :singular_resource => true
Which will generate the routes:
GET /applications
GET /applications/new
POST /applications
GET /application/:id
GET /application/:id/edit
PUT /application/:id
DELETE /application/:id

Resources