Skip to content

About

A demo of using Grape with Roar and some non-trivial HAL presenters.

Resources

Stars

17 stars

Watchers

3 watching

Forks

Repository files navigation

Grape API with Roar

Tests Rubocop Coverage Status

A Grape API that uses Roar to serve HAL hypermedia, including CRUD operations, pagination, templated links, and Swagger documentation.

Run

Use Ruby 3.3 or newer. This branch uses an ActiveModel Spline generated on demand, with no database or persistent writes.

bundle install
RACK_ENV=development bundle exec puma -p 9292

Open localhost:9292/api to explore the API's HAL links, or localhost:9292/api/swagger_doc for Swagger documentation.

POST and PUT JSON

Create a spline by posting a JSON object nested under spline:

curl --include http://localhost:9292/api/splines \
  --header 'Content-Type: application/json' \
  --data '{"spline":{"reticulated":true}}'

The response is 201 Created with the spline's uuid, reticulated value, and HAL links. Send a PUT to an individual spline URL to update it:

curl --include --request PUT http://localhost:9292/api/splines/123 \
  --header 'Content-Type: application/json' \
  --data '{"spline":{"reticulated":false}}'

The response is 200 OK with uuid: "123" and reticulated: false. Both endpoints also accept Content-Type: application/hal+json. The default branch's dummy model accepts any UUID and does not persist writes; 123 is an example identifier, not the UUID generated by POST.

Hyperclient

Hyperclient can create, list, update, and delete splines through the API. See splines_endpoint_with_hyperclient_spec.rb for the corresponding request coverage.

With the server running, open a second terminal:

bundle exec irb

Reuse one client for this sequence. Hyperclient's default middleware encodes Ruby Hash request bodies as HAL JSON, and the returned self links handle each branch's identifier format. The final call deletes only the spline created by this example, not the collection:

require 'hyperclient'

client = Hyperclient.new('http://localhost:9292/api')
spline = client.splines._post(spline: { reticulated: true })
puts spline._links.self._url
puts spline.reticulated

spline = spline._put(spline: { reticulated: false })
puts spline.reticulated

client.splines(size: 2).each do |item|
  puts "#{item._links.self._url}: #{item.reticulated}"
end

spline._delete

Passing size: 2 expands a fresh collection link after POST instead of reusing its cached response. Hyperclient follows pagination links automatically.

On master, writes are nonpersistent: the collection lists generated samples, not the spline created by POST. Update and delete demonstrate the API contract without changing later collections. The same sequence on the database-backed branches persists changes and deletes the created record.

Development

bundle exec rake spec
bundle exec rubocop
# Run both:
bundle exec rake

Tests generate HTML coverage in coverage/index.html and LCOV coverage in coverage/lcov.info. CI tests Ruby 3.3, 3.4, and 4.0 across Grape 2, 3, and 4, including Rack 2 and 3 compatibility, and uploads combined coverage to Coveralls.

The committed lockfile provides the default development bundle. CI resolves each compatibility combination independently using GRAPE_VERSION and RACK_VERSION. To try another combination locally, save the lockfile first, remove it, and run bundle install with those environment variables; restore the default lockfile afterward.

Each active example branch runs its own branch-specific test and lint workflows. This branch requires no database service.

Other Examples

The three active branches share the HAL API, with different model and persistence examples:

Branch Model Database
master ActiveModel None; generated splines, nonpersistent writes
with-mongoid Mongoid MongoDB
with-activerecord ActiveRecord PostgreSQL

Copyright and License

Copyright (c) 2014-2025 Daniel Doubrovkine

MIT License, see LICENSE for details.

About

A demo of using Grape with Roar and some non-trivial HAL presenters.

Resources

Stars

17 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages