-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.rb
More file actions
88 lines (75 loc) · 1.5 KB
/
app.rb
File metadata and controls
88 lines (75 loc) · 1.5 KB
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
require "json"
require "sinatra"
require "time"
set :root, File.dirname(__FILE__)
set :bind, ENV.fetch("BIND", "0.0.0.0")
set :port, Integer(ENV.fetch("PORT", "9000"))
set :server, :puma
APIS = [
{
method: "GET",
path: "/api/ping",
description: "Simple ping endpoint"
},
{
method: "GET",
path: "/api/time",
description: "Returns current UTC time"
},
{
method: "POST",
path: "/api/echo",
description: "Echos back JSON or text payload"
}
].freeze
helpers do
def json(data, status: 200)
content_type :json
halt status, JSON.generate(data)
end
def request_body_string
request.body.rewind
request.body.read.to_s
end
def parse_json_body(raw)
return nil if raw.strip.empty?
JSON.parse(raw)
rescue JSON::ParserError
nil
end
end
get "/" do
content_type :html
erb :index, locals: { apis: APIS }
end
get "/api/ping" do
json({ ok: true, message: "pong" })
end
get "/api/time" do
json({ ok: true, utc: Time.now.utc.iso8601 })
end
post "/api/echo" do
raw = request_body_string
parsed = parse_json_body(raw)
json(
{
ok: true,
content_type: request.media_type,
raw: raw,
json: parsed
}
)
end
not_found do
wants_json = request.path_info.start_with?("/api/")
return erb(:not_found) unless wants_json
json(
{
ok: false,
error: "not_found",
message: "No route matches #{request.request_method} #{request.path_info}",
available_apis: APIS
},
status: 404
)
end