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.
42 43 44 |
# File 'lib/json/ld/conneg.rb', line 42 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.
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/json/ld/conneg.rb', line 53 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.
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 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/json/ld/conneg.rb', line 73 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 = begin links.find_link(['rel', JSON_LD_NS + "context"]).href rescue StandardError nil end frame = begin links.find_link(['rel', JSON_LD_NS + "frame"]).href rescue StandardError nil end 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 StandardError http_error(500, $ERROR_INFO.) end |