Class: Itsi::Server::Config::Endpoint

Inherits:
Middleware
  • Object
show all
Defined in:
lib/itsi/server/config/middleware/endpoint/endpoint.rb

Constant Summary collapse

InvalidHandlerException =
Class.new(StandardError)

Instance Method Summary collapse

Methods included from ConfigHelpers

included, load_and_register, #normalize_keys!

Constructor Details

#initialize(location, path = "", handler = nil, http_methods: [], nonblocking: false, script_name: nil, &handler_proc) ⇒ Endpoint

Returns a new instance of Endpoint.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/itsi/server/config/middleware/endpoint/endpoint.rb', line 36

def initialize(location, path="", handler=nil, http_methods: [], nonblocking: false, script_name: nil, &handler_proc)
  raise "Can not combine a controller method and inline handler" if handler && handler_proc
  handler_proc = location.controller.method(handler).to_proc if handler.is_a?(Symbol) || handler.is_a?(String)

  super(
    location,
    {
      paths: Array(path),
      handler: handler_proc,
      http_methods: http_methods,
      nonblocking: nonblocking,
      script_name: script_name
    }
  )

  num_required, keywords = Itsi::Server::TypedHandlers::SourceParser.extract_expr_from_source_location(handler_proc)
  params_schema = keywords[:params]
  response_schema = keywords[:response_format]
  exception = nil
  if params_schema && num_required > 1
    exception = InvalidHandlerException.new("Cannot accept multiple required parameters in a single endpoint. A single typed or untyped params argument is supported")
  end
  if num_required > 2
    exception = InvalidHandlerException.new("Cannot accept more than two required parameters in a single endpoint. An can either accept a single request argument, or a request and a params argument (which may be typed or untyped). You can also use keyword arguments to anchor response types")
  end
  if num_required == 0
    exception = InvalidHandlerException.new("Cannot accept zero required parameters in a single endpoint. Endpoint must accept a request parameter")
  end
  if response_schema && !(handler_proc.binding.eval(response_schema) rescue false)
    exception = InvalidHandlerException.new("Response Schema by name `#{response_schema}` not found.")
  end
  if params_schema && !(handler_proc.binding.eval(params_schema) rescue false)
    exception = InvalidHandlerException.new("Params Schema by name `#{params_schema}` not found.")
  end

  if exception
    exception.set_backtrace([handler_proc.source_location.join(":")] + caller)
    raise exception
  end

  accepts_params = !params_schema.nil? || num_required > 1

  if accepts_params
    @params[:handler] = Itsi::Server::TypedHandlers.handler_for(@params[:handler], params_schema)
  end
end

Instance Method Details

#build!Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/itsi/server/config/middleware/endpoint/endpoint.rb', line 83

def build!
  params = @params
  app = {
    preloader: -> { params[:handler] },
    nonblocking: @params[:nonblocking],
    script_name: @params[:script_name]
  }

  if @params[:paths] == [""] && @params[:http_methods].empty?
    location.middleware[:app] = app
    location.location("*") do
      @middleware[:app] = app
    end
  else
    @params[:paths] << "" if @params[:paths].empty?
    location.location(*@params[:paths], methods: @params[:http_methods]) do
      @middleware[:app] = app
    end
  end
end