Dead simple parser / deserializer for json api (https://jsonapi.org/)
Install
gem 'jsonapi-unwrapper', '~> 0.0.3'
or
gem install jsonapi-unwrapper
Having issues?
Please let me know and create a issue
Use
Basic Example
require "jsonapi-unwrapper" json = { "data" => { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" }, "relationships" => { "pet" => { "data" => { "id" => 1, "type" => "pets" }, }, }, }, "included" => [ { "id" => 1, "type" => "pets", "attributes" => { "type" => "turtle", "name" => "Josef", }, }, ], } parsed = JsonApiUnwrapper.call(json) parsed["id"] # => 1 parsed["type"] # => "users" parsed["name"] # => "Joe" parsed["pet"]["id"] # => 1 parsed["pet"]["type"] # => "pets" parsed["pet"]["name"] # => "Josef"
Multiple Entities
json = { "data" => [ { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" } }, { "id" => 2, "type" => "users", "attributes" => { "name" => "Tom" } }, ] } parsed = JsonApiUnwrapper.call(json) # Returns an array of parsed entities
Edge Cases
Nil or Missing Data:
JsonApiUnwrapper.call({ "data" => nil }) # => nil JsonApiUnwrapper.call({}) # => nil
Missing Attributes:
json = { "data" => { "id" => 1, "type" => "users" } } parsed = JsonApiUnwrapper.call(json) # Attributes will be an empty hash
Relationships Without Included Resources:
json = { "data" => { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" }, "relationships" => { "pet" => { "data" => { "id" => 1, "type" => "pets" } } } }, "included" => [] } parsed = JsonApiUnwrapper.call(json) parsed["pet"] # => { "id" => 1, "type" => "pets" } (resource identifier returned)
Resource Meta and Links:
json = { "data" => { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" }, "meta" => { "version" => 2 }, "links" => { "self" => "http://example.com/users/1" } } } parsed = JsonApiUnwrapper.call(json) parsed["meta"] # => { "version" => 2 } parsed["links"] # => { "self" => "http://example.com/users/1" }
Relationship Meta and Links:
json = { "data" => { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" }, "relationships" => { "pet" => { "data" => { "id" => 1, "type" => "pets" }, "meta" => { "count" => 1 }, "links" => { "self" => "http://example.com/users/1/relationships/pet" } } } }, "included" => [ { "id" => 1, "type" => "pets", "attributes" => { "name" => "Josef" } } ] } parsed = JsonApiUnwrapper.call(json) parsed["pet"]["_meta"] # => { "count" => 1 } parsed["pet"]["_links"] # => { "self" => "http://example.com/users/1/relationships/pet" }
Null Relationships:
json = { "data" => { "id" => 1, "type" => "users", "attributes" => { "name" => "Joe" }, "relationships" => { "pet" => { "data" => nil } } } } parsed = JsonApiUnwrapper.call(json) parsed["pet"] # => nil
Output Structure
The unwrapped output includes:
id: The resource identifiertype: The resource type (always preserved, takes precedence over any attribute named "type")- All attributes from the
attributesobject - All relationships as nested objects/arrays
links: Resource-level links (if present)meta: Resource-level meta (if present)_links: Relationship-level links (if present, prefixed with underscore to avoid conflicts)_meta: Relationship-level meta (if present, prefixed with underscore to avoid conflicts)
Error Handling
The library handles missing or malformed data gracefully:
- Returns
nilifdataisnilor missing - Returns empty hash
{}ifattributesis missing - Returns resource identifier
{id, type}for relationships that don't have corresponding included resources - Returns
nilfor null relationships
Contributing
Feel free to create a pull request