Class: JsonapiCompliable::Deserializer

Inherits:
Object
  • Object
show all
Defined in:
lib/jsonapi_compliable/deserializer.rb

Overview

Responsible for parsing incoming write payloads

Given a PUT payload like:

{
  data: {
    id: '1',
    type: 'posts',
    attributes: { title: 'My Title' },
    relationships: {
      author: {
        data: {
          id: '1',
          type: 'authors'
        }
      }
    }
  },
  included: [
    {
      id: '1'
      type: 'authors',
      attributes: { name: 'Joe Author' }
    }
  ]
}

You can now easily deal with this payload:

deserializer.attributes
# => { id: '1', title: 'My Title' }
deserializer.meta
# => { type: 'posts', method: :update }
deserializer.relationships
# {
#   author: {
#     meta: { ... },
#     attributes: { ... },
#     relationships: { ... }
#   }
# }

When creating objects, we accept a temp-id so that the client can track the object it just created. Expect this in meta:

{ type: 'authors', method: :create, temp_id: 'abc123' }

Instance Method Summary collapse

Constructor Details

#initialize(payload, env) ⇒ Deserializer

Returns a new instance of Deserializer.

Parameters:

  • payload (Hash)

    The incoming payload with symbolized keys

  • env (Hash)

    the Rack env (e.g. request.env).



50
51
52
53
54
55
# File 'lib/jsonapi_compliable/deserializer.rb', line 50

def initialize(payload, env)
  @payload = payload || {}
  @payload = @payload[:_jsonapi] if @payload.has_key?(:_jsonapi)
  @env = env
  validate_content_type
end

Instance Method Details

#attributesHash

Returns the raw :attributes hash + id.

Returns:

  • (Hash)

    the raw :attributes hash + id



76
77
78
79
80
# File 'lib/jsonapi_compliable/deserializer.rb', line 76

def attributes
  @attributes ||= raw_attributes.tap do |hash|
    hash[:id] = id if id
  end
end

#attributes=(attrs) ⇒ Object

Override the attributes # @see #attributes



84
85
86
# File 'lib/jsonapi_compliable/deserializer.rb', line 84

def attributes=(attrs)
  @attributes = attrs
end

#dataHash

Returns the raw :data value of the payload.

Returns:

  • (Hash)

    the raw :data value of the payload



66
67
68
# File 'lib/jsonapi_compliable/deserializer.rb', line 66

def data
  @payload[:data] || {}
end

#idString

Returns the raw :id value of the payload.

Returns:

  • (String)

    the raw :id value of the payload



71
72
73
# File 'lib/jsonapi_compliable/deserializer.rb', line 71

def id
  data[:id]
end

#include_directive(memo = {}, relationship_node = nil) ⇒ Hash

Parses the relationships recursively and builds an all-hash include directive like

{ posts: { comments: {} } }

Relationships that have been marked for destruction will NOT be part of the include directive.

Returns:

  • (Hash)

    the include directive



117
118
119
120
121
122
123
124
125
# File 'lib/jsonapi_compliable/deserializer.rb', line 117

def include_directive(memo = {}, relationship_node = nil)
  relationship_node ||= relationships

  relationship_node.each_pair do |name, relationship_payload|
    merge_include_directive(memo, name, relationship_payload)
  end

  memo
end

#metaHash

‘meta’ information about this resource. Includes:

type: the jsonapi type method: create/update/destroy/disassociate. Based on the request env or the method within the relationships hash temp_id: the temp-id, if specified

Returns:

  • (Hash)


95
96
97
98
99
100
101
# File 'lib/jsonapi_compliable/deserializer.rb', line 95

def meta
  {
    type: data[:type],
    temp_id: data[:'temp-id'],
    method: method
  }
end

#relationshipsHash

Returns the relationships hash.

Returns:

  • (Hash)

    the relationships hash



104
105
106
# File 'lib/jsonapi_compliable/deserializer.rb', line 104

def relationships
  @relationships ||= process_relationships(raw_relationships)
end

#validate_content_typeObject

checks Content-Type header and prints a warning if it doesn’t seem correct



58
59
60
61
62
63
# File 'lib/jsonapi_compliable/deserializer.rb', line 58

def validate_content_type
  content_type = @env['CONTENT_TYPE'] || ""
  if !(content_type.include?("application/json") || content_type.include?("application/vnd.api+json"))
    print("WARNING - JSONAPI Compliable :: Content-Type header appears to be set to an invalid value: #{content_type}\n")
  end
end