Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Build a Web API with Hanami

Build a Web API with Hanami

Today, building a web app usually includes building a web API. In Ruby, you can pick one of common options, Rails or Sinatra, or a new interesting one: Hanami. I'll present in the talk the reasons that pushed me to pick Hanami to develop a web API, a quick tour of the framework and its basics, and how to use it to develop a web API.

code example: https://github.com/toch/takeoffconf2016-jsonapi

Christophe Philemotte

October 21, 2016
Tweet

More Decks by Christophe Philemotte

Other Decks in Programming

Transcript

  1. lib ├── takeoffconf │ ├── entities │ ├── mailers │

    └── repositories └── takeoffconf.rb
  2. # spec/api/features/list_speakers_spec.rb require 'api_helper' describe 'List speakers' do it 'is

    successful' do header 'Content-Type', 'application/json;' get '/api/speakers' expect(last_response).must_be :ok? expect(last_response.content_type) .must_include "application/json" end
  3. it 'is empty by default' do header 'Content-Type', 'application/json;' get

    '/api/speakers' expect(last_response.body).must_equal '[]' end end
  4. # api/application.rb module Api class Application < Hanami::Application configure do

    # ... default_request_format :json default_response_format :json body_parsers :json end end end
  5. # spec/api/features/list_speakers_spec.rb #... describe 'List speakers' do # ... describe

    'When speakers are recorded' do before do SpeakerRepository.clear SpeakerRepository.create(Speaker.new(name: 'Christophe Philemotte', twitter: '_toch', talk: 'Build a Web API with Hanami')) end
  6. it 'returns an array of those speakers' do header 'Content-Type',

    'application/json;' get '/api/speakers' expect(last_response.body).must_include "\"name\":\"Christophe Philemotte\",\"twitter\":\"_toch\",\"talk\":\"Build a Web API with Hanami\"" end end end
  7. # db/migrations/20161019092946_create_speakers.rb Hanami::Model.migration do change do create_table :speakers do primary_key

    :id column :name, String, null: false column :twitter, String column :talk, String, null: false end end end
  8. # lib/takeoffconf.rb # ... mapping do collection :speakers do entity

    Speaker repository SpeakerRepository attribute :id, Integer attribute :name, String attribute :twitter, String attribute :talk, String end end # ...
  9. # apps/api/controllers/speakers/list.rb module Api::Controllers::Speakers class List include Api::Action accept :json

    expose :speakers def call(params) @speakers = SpeakerRepository.all end end end
  10. # apps/api/views/speakers/list.rb require 'json' module Api::Views::Speakers class List include Api::View

    layout false def render _raw JSON.dump(speakers.map{ |speaker| speaker.to_h }) end end end