2010-04-10 5 views
10

Je travaille sur la construction des URL de mon API REST avant de commencer à écrire du code. Rails REST magique est fantastique, mais je suis un peu gêné la mise en forme d'une URL telle que:Ruby on Rails - différencier les ressources pluriel et singulier dans une API REST

http://myproject/projects/5

où Project est ma ressource et 5 est le project_id. Je pense que si un utilisateur cherche à récupérer tous leurs projets, alors un HTTP GET respectif http://myproject/projects a du sens. Cependant, s'ils cherchent à récupérer des informations sur une ressource singulière, comme un projet, il est logique d'avoir http://myproject/project/5 par rapport à http://myproject/projects/5. Est-il préférable d'éviter ce mal de tête, ou certains d'entre vous partagent une préoccupation similaire et même mieux - avoir une solution de travail?

+2

Je dis aller avec le courant. Convention sur la configuration, souvenez-vous? – JRL

Répondre

17

Rails (3) a beaucoup de conventions quand il s'agit de singulier vs pluriel. Par exemple, les classes de modèles sont toujours au singulier (Person), alors que les tables correspondantes sont toujours au pluriel (people). (Par exemple, Person.all correspond à select * from people.)

Pour les itinéraires, il existe un concept de ressource singulière ainsi qu'une ressource plurielle. Donc, si vous avez fait resource :account alors vous obtiendrez des chemins comme /account pour le chemin par défaut ou /account/edit pour un chemin vers un formulaire pour éditer le compte. (Notez que Rails utilise /account avec une méthode PUT pour mettre à jour le compte.) /account/edit est un formulaire pour modifier le compte, qui est une ressource distincte du compte lui-même.) Si vous avez fait resources :people, cependant, vous obtiendrez des chemins comme /people , /people/1 et /people/1/edit. Les chemins eux-mêmes indiquent s'il ne peut y avoir qu'une seule instance d'un type donné de ressource, ou s'il peut y avoir plusieurs instances distinguées par un type d'identifiant.

3

Je suis d'accord, aller avec le courant. Considérez comment l'URL forme une hiérarchie.

La racine de votre site web se trouve là où vous commencez à accéder à n'importe quoi.

/projects/réduit la taille à seulement les projets, et rien d'autre. Des projets, vous pouvez faire beaucoup de choses,/list,/index /,/export, etc ... le/id limite les choses encore plus loin.

À chaque/la portée de ce qui devient plus étroit, et je pense que c'est logique.

Une autre programmation concerne les règles arbitraires. Les index commençant à 1 vs 0, et ainsi de suite. Toute personne travaillant avec vos URLs triera les choses rapidement.

0

Il existe des cas où un chemin singulier vers une ressource est utile. Si vos ID de ressource sont des noms définis par l'utilisateur non numériques, les conflits d'acheminement sont possibles. Exemple:

/applications/new -> créer une nouvelle application ou afficher l'application de l'utilisateur nommée nouvelle?

Dans cette situation, vous pouvez choisir de limiter l'entrée d'utilisateur pour éviter le choc, ou, ce qui peut être contourné en remplaçant la valeur par défaut Rails 3 Comportement:

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 

Puis lorsque vous spécifiez une nouvelle route de la ressource:

resources :applications, :singular_resource => true 

qui va générer les routes:

GET  /applications 
    GET  /applications/new 
    POST /applications 
    GET  /application/:id 
    GET  /application/:id/edit 
    PUT  /application/:id 
    DELETE /application/:id 
Questions connexes