forked from ruby-grape/grape
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathendpoint.rb
144 lines (126 loc) · 3.64 KB
/
endpoint.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
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
135
136
137
138
139
140
141
142
143
144
require 'rack'
require 'grape'
require 'hashie'
module Grape
# An Endpoint is the proxy scope in which all routing
# blocks are executed. In other words, any methods
# on the instance level of this class may be called
# from inside a `get`, `post`, etc. block.
class Endpoint
def self.generate(options = {}, &block)
c = Class.new(Grape::Endpoint)
c.class_eval do
@block = block
@options = options
end
c
end
class << self
attr_accessor :block, :options
end
def self.call(env)
new.call(env)
end
attr_reader :env, :request
# The parameters passed into the request as
# well as parsed from URL segments.
def params
@params ||= Hashie::Mash.new.deep_merge(request.params).deep_merge(env['rack.routing_args'] || {})
end
# The API version as specified in the URL.
def version; env['api.version'] end
# End the request and display an error to the
# end user with the specified message.
#
# @param message [String] The message to display.
# @param status [Integer] the HTTP Status Code. Defaults to 403.
def error!(message, status=403)
throw :error, :message => message, :status => status
end
# Set or retrieve the HTTP status code.
#
# @param status [Integer] The HTTP Status Code to return for this request.
def status(status = nil)
if status
@status = status
else
return @status if @status
case request.request_method.to_s.upcase
when 'POST'
201
else
200
end
end
end
# Set an individual header or retrieve
# all headers that have been set.
def header(key = nil, val = nil)
if key
val ? @header[key.to_s] = val : @header.delete(key.to_s)
else
@header
end
end
# Allows you to define the response body as something other than the
# return value.
#
# @example
# get '/body' do
# body "Body"
# "Not the Body"
# end
#
# GET /body # => "Body"
def body(value = nil)
if value
@body = value
else
@body
end
end
# Allows you to make use of Grape Entities by setting
# the response body to the serializable hash of the
# entity provided in the `:with` option. This has the
# added benefit of automatically passing along environment
# and version information to the serialization, making it
# very easy to do conditional exposures. See Entity docs
# for more info.
#
# @example
#
# get '/users/:id' do
# present User.find(params[:id]),
# :with => API::Entities::User,
# :admin => current_user.admin?
# end
def present(object, options = {})
entity_class = options.delete(:with)
object.class.ancestors.each do |potential|
entity_class ||= self.class.options[:representations][potential]
end
if entity_class
embeds = {:env => env}
embeds[:version] = env['api.version'] if env['api.version']
body entity_class.represent(object, embeds.merge(options))
else
body object
end
end
def call(env)
@env = env
@header = {}
@request = Rack::Request.new(@env)
run_filters self.class.options[:befores]
response_text = instance_eval &self.class.block
run_filters self.class.options[:afters]
[status, header, [body || response_text]]
end
protected
def run_filters(filters)
(filters || []).each do |filter|
instance_eval &filter
end
end
end
end