Sha256: 8b683654aed01fa2a9ef8f43d0ee3956a27ec772ae8973a92dc5c918855c3883

Contents?: true

Size: 1.72 KB

Versions: 4

Compression:

Stored size: 1.72 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
      params = @request.params.merge(args)
      begin
        payload = @request.body.read
        body = payload.empty? ? {} : JSON.parse(payload, symbolize_names: true)
        params = params.merge(body)
        result = handler.call(@request.env['readmodel.state'], params, env)
        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,
          params: params
        })
      end
    end

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

  end

end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
es-readmodel-1.0.2 lib/es_readmodel/api.rb
es-readmodel-1.0.1 lib/es_readmodel/api.rb
es-readmodel-1.0.0 lib/es_readmodel/api.rb
es-readmodel-0.1.0 lib/es_readmodel/api.rb