{"id":15487956,"url":"https://github.com/dblock/grape-with-roar-walkthrough","last_synced_at":"2025-09-20T05:32:47.807Z","repository":{"id":22827814,"uuid":"26174866","full_name":"dblock/grape-with-roar-walkthrough","owner":"dblock","description":"Live coding of a rudimentary Grape+Roar HAL API.","archived":false,"fork":false,"pushed_at":"2024-02-29T01:14:11.000Z","size":7,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-28T21:05:41.414Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dblock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-04T15:25:33.000Z","updated_at":"2021-03-14T14:56:52.000Z","dependencies_parsed_at":"2024-10-27T17:29:29.604Z","dependency_job_id":null,"html_url":"https://github.com/dblock/grape-with-roar-walkthrough","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dblock%2Fgrape-with-roar-walkthrough","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dblock%2Fgrape-with-roar-walkthrough/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dblock%2Fgrape-with-roar-walkthrough/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dblock%2Fgrape-with-roar-walkthrough/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dblock","download_url":"https://codeload.github.com/dblock/grape-with-roar-walkthrough/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233566907,"owners_count":18695286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T06:45:01.698Z","updated_at":"2025-09-20T05:32:42.470Z","avatar_url":"https://github.com/dblock.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"A live coding exercise for creating a Hypermedia API w/ Grape and Roar for [this talk](http://www.meetup.com/API-Craft-NYC/events/209294892).\n\n#### Create Gemfile\n\n```ruby\nsource 'http://rubygems.org'\n\ngem 'grape'\ngem 'grape-roar'\n```\n\nRun `bundle install`.\n\n#### Create an API Root\n\nCreate `api.rb`.\n\n```ruby\nclass Api \u003c Grape::API\n  format :json\n\n  desc 'Root of the Hypermedia API.'\n  get do\n    { foo: 'bar' }\n  end\nend\n```\n\nCreate `config.ru`.\n\n```ruby\n$LOAD_PATH.unshift(File.dirname(__FILE__))\n\nrequire 'rubygems'\nrequire 'bundler/setup'\n\nBundler.require :default\n\nrequire 'api'\n\nrun Api\n```\n\nRun `rackup`, browse to http://localhost:9292, see the API.\n\n#### Create a Model\n\nAdd `activemodel` to Gemfile.\n\n```ruby\ngem 'activemodel', require: 'active_model'\n```\n\nCreate `models/spline.rb`.\n\n```ruby\nclass Spline\n  include ActiveModel::Model\n\n  attr_accessor :uuid\n  attr_accessor :reticulated\n\n  def initialize(attrs = { reticulated: [true, false].sample })\n    super(attrs)\n    @uuid ||= SecureRandom.uuid\n    @reticulated = !!attrs[:reticulated]\n  end\nend\n```\n\n#### Return a Spline in the API\n\nAdd to `api.rb`.\n\n```ruby\n  resource :splines do\n    desc 'Return a spline.'\n    get ':uuid' do\n      Spline.new(uuid: params[:uuid])\n    end\n  end\n```\n\nYou can navigate to http://localhost:9292/splines/1 and see this `spline.to_s`.\n\nMake a presenter in `presenters/spline_presenter.rb`.\n\n```ruby\nmodule SplinePresenter\n  include Roar::JSON::HAL\n  include Roar::Hypermedia\n  include Grape::Roar::Representer\n\n  property :uuid\n  property :reticulated\n\n  link :self do\n    \"http://localhost:9292/splines/#{uuid}\"\n  end\nend\n```\n\nRequire JSON+HAL in `config.ru`.\n\n```ruby\nrequire 'roar/representer'\nrequire 'roar/json'\nrequire 'roar/json/hal'\n\nrequire 'presenters/spline_presenter'\n```\n\nPresent the spline in `api.rb`.\n\n```ruby\ndesc 'Return a spline.'\nget ':uuid' do\n  present Spline.new(uuid: params[:uuid]), with: SplinePresenter\nend\n```\n\nSee it at http://localhost:9292/splines/123.\n\n#### Return a Collection of Splines\n\nCreate a `presenters/splines_presenter.rb`.\n\n``` ruby\nmodule SplinesPresenter\n  include Roar::JSON::HAL\n  include Roar::Hypermedia\n  include Grape::Roar::Representer\n\n  collection :to_a, extend: SplinePresenter, as: :splines, embedded: true\nend\n```\n\nRequire it.\n\n```ruby\nrequire 'presenters/splines_presenter'\n```\n\nPresent splines.\n\n```ruby\ndesc 'Return a few splines.'\nget do\n  present 5.times.map { Spline.new }, with: SplinesPresenter\nend\n```\n\n#### Add a Root Presenter\n\nCreate `presenters/root_presenter.rb`.\n\n```ruby\nmodule RootPresenter\n  include Roar::JSON::HAL\n  include Roar::Hypermedia\n  include Grape::Roar::Representer\n\n  link :self do\n    \"http://localhost:9292\"\n  end\n\n  link :splines do\n    \"http://localhost:9292/splines\"\n  end\n\n  link :spline do |opts|\n    {\n      href: \"http://localhost:9292/splines/{uuid}\",\n      templated: true\n    }\n  end\nend\n```\n\nRequire it.\n\n```ruby\nrequire 'presenters/root_presenter'\n```\n\nPresent it.\n\n```ruby\ndesc 'Root of the Hypermedia API.'\nget do\n  present self, with: RootPresenter\nend\n```\n\n#### Try It\n\n``` ruby\nrequire 'hyperclient'\n\nclient = Hyperclient.new('http://localhost:9292')\n\nclient.splines.count\n\nclient.splines.to_a.each do |spline|\n    puts \"Spline #{spline.uuid} is #{spline.reticulated ? 'reticulated' : 'not reticulated'}.\"\nend\n```\n\n### LICENSE\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdblock%2Fgrape-with-roar-walkthrough","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdblock%2Fgrape-with-roar-walkthrough","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdblock%2Fgrape-with-roar-walkthrough/lists"}