Skip to content

Instantly share code, notes, and snippets.

@berkes
Last active November 4, 2021 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save berkes/e164c79bab468759882d2878717072dd to your computer and use it in GitHub Desktop.
Save berkes/e164c79bab468759882d2878717072dd to your computer and use it in GitHub Desktop.
HAL Libraries for Ruby - evaluation

HAL API libraries for Ruby

https://github.com/mikekelly/hal_specification/wiki/Libraries#ruby used as seed.

Evaluation of various HAL clients to build and consume HAL JSON APIs for Plannel. Evaluation purely by reading code and README. No Proof of Concept or experience with any of the libs.

The evaluation was done with a clear goal in mind: build the HTTP+HAL+JSON adapter on an existing business-domain that (hexagonal architecture). Preferably using Sinatra, since this HTTP adapter does not interact with databases or other plumbing etc: only with Models (Root Aggregates) and Commands. Clean, and easy to understand architecture is an important criteria. As are some other criteria: this is very opinionated and might not match what you are looking for, at all: it may very well be that something listed as "con" is a "pro" for you.

Tests for the API need a HAL client, the implementation needs a server. Client and server need not be the same library.

Con is -, pro is +.

Clients

Cetacean https://github.com/benhamill/cetacean#readme The HAL client that does almost nothing for/to you.

  • + Very lean
  • + Focus on finding and getting links, less on payload.
  • - Poor support for creating/updating, focus very much on GETting.
  • - Needs additional layer to deserialize into models/objects.
  • - Tightly coupled to Faraday
  • - Faraday is broadly featured (no SRP), from testing support to streaming support, most of which we don't need or want to implement outside of the HTTP client.

Excon::Hypermedia https://github.com/blendle/excon-hypermedia Teaches Excon how to talk to HyperMedia APIs.

  • + Simple and very small (though Excon is rather large)
  • - tightly coupled to Excon. https://github.com/excon/excon
  • - no documentation or mention of update/delete/create actions: only GET is covered.
  • - Excon is broadly featured (no SRP), from testing support to streaming support, most of which we don't need or want to implement outside of the HTTP client.

Frenetic https://github.com/dlindahl/frenetic An opinionated Ruby-based Hypermedia API (HAL+JSON) client.

  • + small and focused
  • + HAL+JSON only
  • + designed around links entirely: everything is discovered through links
  • + caching (not fetching resources again) built in, when discovering resources.
  • - no support for create/update/delete resources (yet, mentioned as TODO)
  • - very strongly opinionated. Opinions hardcoded.

Halibut See below, at server. Since Halibut only handles de/serializing, it can be used to build models/resources from JSON responses too. But it lacks any HTTP, which might be a good thing (SRP!)

Hactor https://github.com/mikekelly/hactor A framework for building hypermedia clients

  • + tiny, easy to follow and lean codebase
  • + neat concept of callbacks: keep business-logic contained and separate from HTTP and de/serializing plumbing.
  • + Callback idea makes it extremely easy to test.
  • - hardly any activity, last commit from 9+ years ago

HyperResource https://github.com/gamache/hyperresource HyperResource is a Ruby client library for hypermedia web services.

  • + designed around links entirely: everything is discovered through links
  • + First class support for curies.
  • + Proper support for GET/POST/PUT/DELETE.
  • - adapter pattern used to abstract discovery from format. But only HAL+JSON is implemented, so rather much complexity and overhead.
  • - Large and unwieldy classes making logic and flow hard to read and follow.
  • - hardly any activity, last commit from 6+ years ago
  • - tightly coupled to Faraday

HalClient https://github.com/pezra/hal-client An easy to use client interface for REST APIs that use HAL.

  • + designed around links entirely: everything is discovered through links
  • + First class support for curies.
  • + Proper support for Pagination
  • + Proper support for GET/POST/PUT/DELETE.
  • + Serializers built in, using simple subclasses.
  • - Tightly coupled to HTTP library, which is a simple and core HTTP handler.
  • - HTTP communication is interwoven with de/serializing and discovery, and even logging, making code hard to follow and hard to test.

Shaf Client https://github.com/sammyhenningsson/shaf_client ShafClient is a hypermedia client using the HAL mediatype.

  • + Actively maintained
  • + uses HAL exclusively
  • + Base Resource class breaks SRP by doing all (http handling to mapping to parsing) but does so in clean and easy to follow code: all responsibilities are abstracted and isolated, then bound together in the God Class Resource.
  • - Tightly coupled to Faraday (even monkeypatches Faraday to add missing features in older versions)
  • - Handles the HTTP, deserializing and error handling all in one. Making it break SRP.
  • - magic method missing flows to magically introduce a DSL for attributes, relations and links: this part is hard to follow.

Servers

Shaf: https://github.com/sammyhenningsson/shaf Shaf is a framework for building hypermedia driven REST APIs.

  • + Actively maintained
  • + uses HAL exclusively
  • + neat architectural choices (well thought out)
  • + very few dependencies
  • - rather large and complex
  • - opinionated
  • - aimed at Rails mostly

Roar: https://github.com/trailblazer/roar Roar is a framework for parsing and rendering REST documents. Nothing more.

  • + Actively maintained
  • + Popular
  • + uses HAL extensively
  • + neat architectural choices (well thought out)
  • + very few dependencies
  • + from the well-architectured trailblazer family (which may be convoluted and daunting, though)
  • - rather large and complex
  • - opinionated
  • - broad focus on all kinds of APIs, not just HAL
  • - A DSL obscuring the actual logic.

Halibut https://github.com/locks/halibut Halibut is a tiny gem that makes it easier to deal with the HAL format.

  • + very small and easy to understand codebase
  • + thin layer of abstraction
  • - No objects or classes to manage resources, instead either a sequential interface, or through blocks. It may be possible to squeeze it into serializer classes, though.
  • - Mostly a DSL to build resources, really.
  • - hardly any activity, last commit from 6+ years ago.

Jsonite https://github.com/crepe/jsonite A tiny, HAL-compliant JSON presenter.

  • + presenter pattern; using proper subclasses to configure resources.
  • + SRP: only presenter, no HTTP or de/serializing
  • - mostly a DSL to set up and configure those presenter subclasses.
  • - dependency on the large and wieldy activeresource just for pluralisation in the DSL etc.
  • - hardly any activity, last commit from 7+ years ago

Yaks https://github.com/plexus/yaks The library that understands hypermedia.

  • + Popular (stars)
  • + has a logo ;)
  • + Concept of tying the configuration, parsing and serializing together in a pipeline. Moving that plumbing away from your controllers into selfcontained units.
  • + Has presenters/serializers (called Mappers) as plain classes.
  • + Strong focus on link building and presenting
  • + Well suited for when complex mapping/serializing is needed
  • - archived and no commit activity in years

HalClient https://github.com/pezra/hal-client HalClient can be used by servers of HAL APIs to interpret the bodies of requests.

See above, under Clients for details on HalClient.

Oat https://github.com/ismasan/oat Adapters-based API serializers with Hypermedia support for Ruby apps. Read the blog post for context and motivation.

  • + Popular (stars)
  • + Adapter architecture to support multiple media types. Clean, easy to follow setup.
  • + Serializers separated from the actual serialization into formats. Making it easy to test.
  • - Adapters bring many features down to lowest common denominator: e.g. format-specific details like curies are naturally not easy due to it mapping only to HAL and not other formats.
  • - When you want to support only one format (HAL) it adds a lot of overhead and complexity due to its focus on offering multiple formats.

Halogen https://github.com/mode/halogen This library provides a framework-agnostic interface for generating HAL+JSON representations of resources in Ruby.

  • + Recent activity and commits
  • + Nice presenter pattern
  • + Focus on HAL.
  • + Focus on serializing (representing) only; no HTTP or media-type plumbing intertwined.
  • + Lots of features to control links in great detail.
  • + Clean middleware-alike setup to extend serialization with own behaviour.
  • + Clean, simple and readable code. Albeit that a lot of the code is merely there to provide the DSL.
  • - Lot of code and complexity in DSL-absctractions to create the presenters.
  • - Modules, instead of subclasses for building the presenters.

HALPresenter https://github.com/sammyhenningsson/hal_presenter HALPresenter is a DSL for creating serializers conforming to JSON HAL. This DSL is highly influenced by ActiveModelSerializers.

  • + Strong focus on performance. See https://gist.github.com/sammyhenningsson/890f7e4d6967883666851eb6aab92adb for their benchmark comparison.
  • + Nice presenter pattern
  • + Focus on HAL.
  • + Focus on serializing (representing) only; no HTTP or media-type plumbing intertwined.
  • + First class support for namespaces and curies
  • + Deserializing (consuming requests) first class feature.
  • + Lots of features to control links in great detail.
  • + Support for authorization based determination of links and attributes (only show/serialize those that a user has access to)
  • - Added complexity by this integration of Pundit(alike) authorization. Authorization controls the links, but doing inside serialization (rather than before serialization) makes this lib more complex than many others.
  • - Lot of code and complexity in DSL-absctractions to create the presenters.
  • - Modules, instead of subclasses for building the presenters.

Tools

Halidator https://github.com/deathbob/halidator Small library for validating hal+json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment