Sha256: 13b185282a495e74b03ec8f21dd5064fda6f592c9a23ae4481300fe60fda8f47

Contents?: true

Size: 1.41 KB

Versions: 2

Compression:

Stored size: 1.41 KB

Contents

require 'rack'
require 'json'
require 'mustermann'

module EsReadModel

  class ApiError < StandardError
  end

  class Api

    def initialize(routes)
      @routes = routes
    end

    def call(env)
      @request = Rack::Request.new(env)
      path = @request.path_info
      @routes.each do |route, handler|
        args = Mustermann.new(route).params(path)
        return invoke_handler(handler, args, env) if args
      end
      return json_response(404, {error: 'path did not match any route'})
    end

    private

    def invoke_handler(handler, args, env)
      return json_response(503, {status: env['readmodel.status']}) unless env['readmodel.available'] == true
      begin
        result = handler.call(@request.env['readmodel.state'], @request.params.merge(args))
        return result ? json_response(200, result) : json_response(404, {error: 'not found in read model'})
      rescue ApiError => ex
        return json_response(400, {
          error: ex.message
        })
      rescue Exception => ex
        return json_response(500, {
          error: "#{ex.class.name}: #{ex.message}",
          backtrace: ex.backtrace
        })
      end
    end

    def json_response(status_code, body)
      result = body.merge({
        _links: { self: @request.fullpath }
      })
      [
        status_code,
        {
          'Content-Type' => 'application/json'
        },
        [result.to_json]
      ]
    end

  end

end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
es-readmodel-0.0.7 lib/es_readmodel/api.rb
es-readmodel-0.0.6 lib/es_readmodel/api.rb