Class: JSON::LD::ContentNegotiation
- Inherits:
-
Object
- Object
- JSON::LD::ContentNegotiation
- Defined in:
- lib/json/ld/conneg.rb
Overview
Rack middleware for JSON-LD content negotiation.
Uses HTTP Content Negotiation to serialize ‘Array` and `Hash` results as JSON-LD using ’profile’ accept-params to invoke appropriate JSON-LD API methods.
Allows black-listing and white-listing of two-part profiles where the second part denotes a URL of a context or frame. (See Writer.accept?)
Works along with ‘rack-linkeddata` for serializing data which is not in the form of an `RDF::Repository`.
Constant Summary collapse
- VARY =
{'Vary' => 'Accept'}.freeze
Instance Attribute Summary collapse
- #app ⇒ #call readonly
Class Method Summary collapse
-
.registered(app) ⇒ void
-
Registers JSON::LD::Rack, suitable for Sinatra application * adds helpers.
-
Instance Method Summary collapse
-
#call(env) ⇒ Array(Integer, Hash, #each)
Handles a Rack protocol request.
-
#initialize(app) ⇒ ContentNegotiation
constructor
A new instance of ContentNegotiation.
-
#serialize(env, status, headers, body) ⇒ Array(Integer, Hash, #each)
Serializes objects as JSON-LD.
Constructor Details
#initialize(app) ⇒ ContentNegotiation
Returns a new instance of ContentNegotiation.
39 40 41 |
# File 'lib/json/ld/conneg.rb', line 39 def initialize(app) @app = app end |
Instance Attribute Details
Class Method Details
Instance Method Details
#call(env) ⇒ Array(Integer, Hash, #each)
Handles a Rack protocol request. Parses Accept header to find appropriate mime-type and sets content_type accordingly.
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/json/ld/conneg.rb', line 50 def call(env) response = app.call(env) body = response[2].respond_to?(:body) ? response[2].body : response[2] case body when Array, Hash response[2] = body # Put it back in the response, it might have been a proxy serialize(env, *response) else response end end |
#serialize(env, status, headers, body) ⇒ Array(Integer, Hash, #each)
Serializes objects as JSON-LD. Defaults to expanded form, other forms determined by presense of ‘profile` in accept-parms.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/json/ld/conneg.rb', line 70 def serialize(env, status, headers, body) # This will only return json-ld content types, possibly with parameters content_types = parse_accept_header(env['HTTP_ACCEPT'] || 'application/ld+json') content_types = content_types.select do |content_type| _, *params = content_type.split(';').map(&:strip) accept_params = params.inject({}) do |memo, pv| p, v = pv.split('=').map(&:strip) memo.merge(p.downcase.to_sym => v.sub(/^["']?([^"']*)["']?$/, '\1')) end JSON::LD::Writer.accept?(accept_params) end if content_types.empty? not_acceptable("No appropriate combinaion of media-type and parameters found") else ct, *params = content_types.first.split(';').map(&:strip) accept_params = params.inject({}) do |memo, pv| p, v = pv.split('=').map(&:strip) memo.merge(p.downcase.to_sym => v.sub(/^["']?([^"']*)["']?$/, '\1')) end # Determine API method from profile profile = accept_params[:profile].to_s.split(' ') # Get context from Link header links = LinkHeader.parse(env['HTTP_LINK']) context = links.find_link(['rel', JSON_LD_NS+"context"]).href rescue nil frame = links.find_link(['rel', JSON_LD_NS+"frame"]).href rescue nil if profile.include?(JSON_LD_NS+"framed") && frame.nil? return not_acceptable("framed profile without a frame") end # accept? already determined that there are appropriate contexts # If profile also includes a URI which is not a namespace, use it for compaction. context ||= Writer.default_context if profile.include?(JSON_LD_NS+"compacted") result = if profile.include?(JSON_LD_NS+"flattened") API.flatten(body, context) elsif profile.include?(JSON_LD_NS+"framed") API.frame(body, frame) elsif context API.compact(body, context) elsif profile.include?(JSON_LD_NS+"expanded") API.(body) else body end headers = headers.merge(VARY).merge('Content-Type' => ct) [status, headers, [result.to_json]] end rescue http_error(500, $!.) end |