- Start Date: (2016-01-28) - RFC PR: https://github.com/rails-api/active_model_serializers/pull/dddd - ActiveModelSerializers Issue: https://github.com/rails-api/active_model_serializers/issues/dddd # Summary Proposal to add a resource routing concern to ActiveModelSerializers for compatibility with JSON API. # Motivation [JSON API spec includes resource routes](https://github.com/rails-api/active_model_serializers/blob/master/docs/jsonapi/schema.md#fetching-data) that differ from the routes generated by by the [Rails router `resource`](https://github.com/rails/rails/blob/v5.0.0.beta1.1/actionpack/lib/action_dispatch/routing/mapper.rb#L1074-L1452) mapping. # Proposal Given [Rails's `resource` router](https://github.com/rails/rails/blob/v5.0.0.beta1.1/guides/source/routing.md): ```ruby resources :contacts do resources :phone_numbers end resources :phone_numbers do resources :contacts end ``` (ouptut of `rake routes` on [peeps](https://github.com/cerebris/peeps) using [JSONAPI::Resources](https://github.com/cerebris/jsonapi-resources) when modified to the above) ```plain Prefix Verb URI Pattern Controller#Action contact_phone_numbers GET /contacts/:contact_id/phone_numbers(.:format) phone_numbers#index POST /contacts/:contact_id/phone_numbers(.:format) phone_numbers#create new_contact_phone_number GET /contacts/:contact_id/phone_numbers/new(.:format) phone_numbers#new edit_contact_phone_number GET /contacts/:contact_id/phone_numbers/:id/edit(.:format) phone_numbers#edit contact_phone_number GET /contacts/:contact_id/phone_numbers/:id(.:format) phone_numbers#show PATCH /contacts/:contact_id/phone_numbers/:id(.:format) phone_numbers#update PUT /contacts/:contact_id/phone_numbers/:id(.:format) phone_numbers#update DELETE /contacts/:contact_id/phone_numbers/:id(.:format) phone_numbers#destroy contacts GET /contacts(.:format) contacts#index POST /contacts(.:format) contacts#create new_contact GET /contacts/new(.:format) contacts#new edit_contact GET /contacts/:id/edit(.:format) contacts#edit contact GET /contacts/:id(.:format) contacts#show PATCH /contacts/:id(.:format) contacts#update PUT /contacts/:id(.:format) contacts#update DELETE /contacts/:id(.:format) contacts#destroy phone_number_contacts GET /phone_numbers/:phone_number_id/contacts(.:format) contacts#index POST /phone_numbers/:phone_number_id/contacts(.:format) contacts#create new_phone_number_contact GET /phone_numbers/:phone_number_id/contacts/new(.:format) contacts#new edit_phone_number_contact GET /phone_numbers/:phone_number_id/contacts/:id/edit(.:format) contacts#edit phone_number_contact GET /phone_numbers/:phone_number_id/contacts/:id(.:format) contacts#show PATCH /phone_numbers/:phone_number_id/contacts/:id(.:format) contacts#update PUT /phone_numbers/:phone_number_id/contacts/:id(.:format) contacts#update DELETE /phone_numbers/:phone_number_id/contacts/:id(.:format) contacts#destroy phone_numbers GET /phone_numbers(.:format) phone_numbers#index POST /phone_numbers(.:format) phone_numbers#create new_phone_number GET /phone_numbers/new(.:format) phone_numbers#new edit_phone_number GET /phone_numbers/:id/edit(.:format) phone_numbers#edit phone_number GET /phone_numbers/:id(.:format) phone_numbers#show PATCH /phone_numbers/:id(.:format) phone_numbers#update PUT /phone_numbers/:id(.:format) phone_numbers#update DELETE /phone_numbers/:id(.:format) phone_numbers#destroy ``` The JSON API resource routing declaration would be: ```ruby contraint mime_type: :json_api do resources :contacts resources :phone_numbers end ``` Where `mime_type: :json_api` constrains the route to requests containing the header `Accept: application/vnd.api+json` (ouptut of `rake routes` on [peeps](https://github.com/cerebris/peeps) using [JSONAPI::Resources](https://github.com/cerebris/jsonapi-resources)) ``` Prefix Verb URI Pattern Controller#Action contact_relationships_phone_numbers GET /contacts/:contact_id/relationships/phone-numbers(.:format) contacts#show_relationship {:relationship=>"phone_numbers"} POST /contacts/:contact_id/relationships/phone-numbers(.:format) contacts#create_relationship {:relationship=>"phone_numbers"} PUT|PATCH /contacts/:contact_id/relationships/phone-numbers(.:format) contacts#update_relationship {:relationship=>"phone_numbers"} DELETE /contacts/:contact_id/relationships/phone-numbers(.:format) contacts#destroy_relationship {:relationship=>"phone_numbers"} contact_phone_numbers GET /contacts/:contact_id/phone-numbers(.:format) phone_numbers#get_related_resources {:relationship=>"phone_numbers", :source=>"contacts"} contacts GET /contacts(.:format) contacts#index POST /contacts(.:format) contacts#create contact GET /contacts/:id(.:format) contacts#show PATCH /contacts/:id(.:format) contacts#update PUT /contacts/:id(.:format) contacts#update DELETE /contacts/:id(.:format) contacts#destroy phone_number_relationships_contact GET /phone-numbers/:phone_number_id/relationships/contact(.:format) phone_numbers#show_relationship {:relationship=>"contact"} PUT|PATCH /phone-numbers/:phone_number_id/relationships/contact(.:format) phone_numbers#update_relationship {:relationship=>"contact"} DELETE /phone-numbers/:phone_number_id/relationships/contact(.:format) phone_numbers#destroy_relationship {:relationship=>"contact"} phone_number_contact GET /phone-numbers/:phone_number_id/contact(.:format) contacts#get_related_resource {:relationship=>"contact", :source=>"phone_numbers"} phone_numbers GET /phone-numbers(.:format) phone_numbers#index POST /phone-numbers(.:format) phone_numbers#create phone_number GET /phone-numbers/:id(.:format) phone_numbers#show PATCH /phone-numbers/:id(.:format) phone_numbers#update PUT /phone-numbers/:id(.:format) phone_numbers#update DELETE /phone-numbers/:id(.:format) phone_numbers#destroy ``` # Drawbacks # Alternatives # Unresolved questions