$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
$ rails g scaffold pet name:string $ rails g scaffold toy name:string pet:references $ rake db:migrate # set a default route, define relationships, etc ...
:created_at, :updated_at end # app/serializers/toy_serializer.rb class ToySerializer < ActiveModel::Serializer attributes :id, :name, :created_at, :updated_at end
:update, :destroy] # GET /pets # GET /pets.json def index render json: Pet.all end # GET /pets/1 # GET /pets/1.json def show render json: @pet end ..... end
:created_at, :updated_at # allow custom inclusion of a single field def include_created_at? if @options.key?(:fields) return @options[:fields][:created_at] end true end end
:created_at, :updated_at # allow custom inclusion of a single field def include_created_at? if @options.key?(:fields) return @options[:fields][:created_at] end true end end "THAT'S BETTER, BUT..."
:created_at, :updated_at end # app/serializers/pet_serializer.rb class PetSerializer < BaseSerializer attributes :name end # app/serializers/toy_serializer.rb class ToySerializer < BaseSerializer attributes :name end
:id, :created_at, :updated_at # allow custom inclusion of ANY field # via options passed in from the controller def include?(field) if @options.key?(:fields) return @options[:fields][field] end super(field) end end
default page size, a max page size, and allow custom requests: /pets?page=2&per_page=100 Opinion! JSON API should separate the primary resource from its related resources when "side-loading" in order to clarify issues of primacy like pagination.
to allow for navigation: Link: <https://v1.api.rubypets.org/pets?page=3&per_page=100>; rel="next", <https://v1.api.rubypets.org/pets?page=9&per_page=100>; rel="last" Possible values for `rel`: first, last, next, prev
a hypermedia content type to be as as navigable as the web itself. REST was a term originally invented by Roy Fielding, but since most "REST" APIs aren't in line with his definition, the term "Hypermedia API" was created. HYPERMEDIA APIS
changes, and promote decoupling and encapsulation, with all the benefits those things bring. On the downside, it is not necessarily the most latency-tolerant design, and caches can get stale if you’re not careful. It may not be as efficient on an individual request level as other designs." Steve Klabnik Designing Hypermedia APIs designinghypermediaapis.com
non-admins) as needed in your controller and serializer layers • HTTPS for all the things • Use token-based security • If you want to build an OAuth provider, don't go it alone. Use a gem like James Coglan's oauth2-provider: https://github.com/songkick/oauth2-provider