1) In genere è meglio essere espliciti sulla visualizzazione delle risorse a riposo. Pertanto, ha senso seguire il paradigma collection/:id/sub-collection/:id
con la tua API.
2) È considerato un anti-modello nel mondo REST di utilizzare qualsiasi cosa diversa dai nomi per le tue raccolte nei tuoi URI. Questo perché le migliori pratiche REST si aspettano che la tua "verbiage" giunga sotto forma di verbi HTTP, e non qualcosa che hai deciso di dichiarare da solo. Questo non è un vincolo REST in alcun modo, ma è considerato la migliore implementazione possibile e consente agli sviluppatori di mantenere le cose coerenti.
I verbi HTTP GET POST PUT e DELETE sono adatti per qualsiasi esigenza del programma. Spesso, se ritieni di aver "bisogno di più verbi" per implementare con successo una funzione, significa davvero che devi espandere il tuo pensiero sulla risorsa su cui viene effettuata tale chiamata.
Ad esempio: se volessi accedere a un utente, il mio primo pensiero potrebbe essere quello di mettere quell'azione sulla classe User
tramite un metodo User#login
. Sarebbe piuttosto strano, però, giusto? Stiamo usando un verbo e ora sappiamo che è un anti-pattern REST.
Invece, se avessimo creato una classe Session
associata? Ora possiamo tranquillamente chiamare Session#create
su una nuova istanza del modello (che è associata a User
) e rimanere RESTful come al diavolo!
Spero davvero che questo aiuti. Ricorda: in caso di dubbio, tieni presente che, indipendentemente da ciò che stai facendo, la community ha trovato un modo per mantenere le cose RESTful, in quanto ci sono alcune applicazioni GRANDI OL là fuori che aderiscono strettamente alle regole di REST.
Aggiorna
Perché non usare un metodo di classe? Non ho visto il tuo codice, ma presumo che tu stia usando qualcosa come i binari per la tua API.
Potresti fare quanto segue:
///items/index.html.erb
<% form_tag items_path, method: :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", name: nil %>
</p>
<% end %>
///items_controller.rb
def index
@items = Item.search(params[:search])
end
///models/item.rb
def self.search(search)
if search
find(:all, conditions: ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
Questa è ovviamente una descrizione degli oggetti abbastanza vaga, ma penso che ti verrà un'idea. In questo modo, utilizzi sempre un verbo HTTP GET e lo fai in modo riposante. L'altra opzione, sì, è usare i parametri di query. Questo ti aiuta a evitare di farlo.