schemaless_rest_api 0.3.4 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c6884db983603d3fe99853d2daf2448c5a112535d427c4dcf93085c03d0d572
4
- data.tar.gz: 233cf6a115128268144a612ff02e5de53c32b4f1dc0cb3e46a53f15ebc776e9d
3
+ metadata.gz: 3ab21f348c0122fbfa54365f8f1ed20c80bcf2f110e522bf8e782315414419e9
4
+ data.tar.gz: a5ac30ed8f1efe06561474fed073f9e270788b74502e85dfcf8e61b11131a21d
5
5
  SHA512:
6
- metadata.gz: 6fddf98f70498d9efee708f86ba28a3ddc4da8b53c029886c964ba8be2078d8bc459d025c50236bb11c9992a8a4ef5edd62d3a05491d8686ac481c2d6a61238a
7
- data.tar.gz: ad73ffe9c66723853b0e0a9dc6ecaeb30371b7b12ceb33267715de10dcac052bb3d2107ad3fd4d93bff978239077d2a9434e526b8a32dc550676145b4d0b7db9
6
+ metadata.gz: a63738895a1ae2c01ecf3a0d81d70978231f3c92493a13f9a72cb111d1b41a6f90fde28f9dddd2de662c9fe7d3e270bdd1f7462870c02516e1a042957f950169
7
+ data.tar.gz: aa2e4411f2aace139b6b9d40edb672e32513d6dcc07a4e6359b2338191dd3bf583f433d9d239f3d7263fde38eb169990290d73e31aa2d2df51b9e7074f55480e
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sinatra"
4
- require "docdsl"
5
4
  require "puma"
6
5
  require "route_downcaser"
6
+ require_relative "server_utils"
7
7
 
8
8
  # Server with endpoints generated based on Entities with CRUD operations for them
9
9
  class RestServer < Sinatra::Base
@@ -11,17 +11,39 @@ class RestServer < Sinatra::Base
11
11
  enable :logging if ENV["debug"] == "true"
12
12
  set :bind, "0.0.0.0"
13
13
  use RouteDowncaser::DowncaseRouteMiddleware
14
+ helpers ServerUtils
14
15
 
15
- register Sinatra::DocDsl
16
+ before do
17
+ @request_id = SecureRandom.uuid
18
+ headers["X-Request-Id"] = @request_id
19
+ headers["Access-Control-Allow-Origin"] = "*"
20
+ log({ msg: "Request"}) if (request.fullpath != "")
21
+ end
16
22
 
17
- page do
18
- title "Schmaless REST API"
19
- header "REST API using models #{Entities.models.keys}"
20
- introduction "REST APIs allowing CRUD on:
21
- #{Entities.models.keys.join("\n")}"
23
+ after do
24
+ log({ msg: "Response", status: response.status }) if (request.fullpath != "")
22
25
  end
23
26
 
24
- doc_endpoint "/docs"
27
+ SWAGGER_FILES = %w[index.css swagger.html swagger-initializer.js swagger-ui-bundle.js swagger-ui-standalone-preset.js swagger-ui.css]
28
+
29
+ SWAGGER_FILES.each do |filename|
30
+ get "/#{filename.gsub(".html", "")}" do
31
+ if filename.end_with? '.json'
32
+ content_type :json
33
+ elsif filename.end_with? '.css'
34
+ content_type :css
35
+ elsif filename.end_with? '.js'
36
+ content_type :js
37
+ end
38
+
39
+ File.read("./lib/schemaless_rest_api/swagger/#{filename}")
40
+ end
41
+ end
42
+
43
+ get "/swagger.json" do
44
+ content_type :json
45
+ SwaggerBuilder.build_swagger_for(Entities.models, request.host_with_port)
46
+ end
25
47
 
26
48
  def has_id?(model, id)
27
49
  Entities.models[model].key?(id)
@@ -31,28 +53,20 @@ class RestServer < Sinatra::Base
31
53
  [404, JSON.generate({ error: "'#{id}' not found" })]
32
54
  end
33
55
 
34
- documentation "Get summary" do
35
- response "Basic basic summary of API"
36
- end
37
56
  get "/" do
38
57
  summary = { models: Entities.models.keys.to_s,
39
- docs_url: "<a href=/docs>/docs</a>" }
58
+ docs_url: "<a href=/swagger>Swagger docs</a>" }
40
59
  summary[:db] = MongoClient.client.summary.to_s if ENV["mongodb"]
41
60
  JSON.generate(summary)
42
- rescue Exception => e
61
+ rescue StandardError => e
43
62
  [500, e.message]
44
63
  end
45
64
 
46
65
  Entities.models.each_key do |model|
47
- documentation "Create instance of #{model}" do
48
- payload "Whatever JSON you want. Needs to be valid JSON"
49
- response "Id of created #{model}"
50
- status 201
51
- end
52
66
  post "/#{model.downcase}" do
53
- response["Access-Control-Allow-Origin"] = "*"
54
- SchemalessRestApi.logger.info "POST #{request.fullpath}"
55
- data = JSON.parse(request.body.read)
67
+ request_body = request.body.read
68
+ data = {}
69
+ data = JSON.parse(request_body) unless request_body.empty?
56
70
  id = ""
57
71
  if data["id"]
58
72
  id = data["id"].to_s
@@ -65,24 +79,17 @@ class RestServer < Sinatra::Base
65
79
  else
66
80
  Entities.models[model][id] = data
67
81
  end
82
+ log "Created #{id}"
68
83
  [201, JSON.generate({ id: id })]
69
84
  end
70
85
 
71
86
  options "/#{model.downcase}" do
72
87
  response["Allow"] = "*"
73
- response["Access-Control-Allow-Origin"] = "*"
74
88
  response["Access-Control-Allow-Methods"] = "*"
75
89
  response["Access-Control-Allow-Headers"] = "*"
76
90
  end
77
91
 
78
- documentation "Retrieve all instances of #{model} or filtered by query param" do
79
- response "Data in #{model}"
80
- query_param :key_to_search_in_data, "Value of key"
81
- status 200
82
- end
83
92
  get "/#{model.downcase}" do
84
- response["Access-Control-Allow-Origin"] = "*"
85
- SchemalessRestApi.logger.info "GET #{request.fullpath}"
86
93
  if ENV["mongodb"]
87
94
  if params == {}
88
95
  JSON.generate(MongoClient.get_all(model))
@@ -97,18 +104,11 @@ class RestServer < Sinatra::Base
97
104
  end
98
105
  return JSON.generate(matching_values)
99
106
  end
100
- rescue Exception => e
107
+ rescue StandardError => e
101
108
  [404, "Nothing found using #{params}. Only first param considered. #{e.message}"]
102
109
  end
103
110
 
104
- documentation "Retrieve specific instance of #{model} by id" do
105
- response "Data in #{model}"
106
- status 200
107
- status 404
108
- end
109
111
  get "/#{model.downcase}/:id" do |id|
110
- response["Access-Control-Allow-Origin"] = "*"
111
- SchemalessRestApi.logger.info "GET #{request.fullpath}"
112
112
  if ENV["mongodb"]
113
113
  results = MongoClient.find(model, id)
114
114
  return not_have(id) unless results.first
@@ -128,15 +128,7 @@ class RestServer < Sinatra::Base
128
128
  response["Access-Control-Allow-Headers"] = "*"
129
129
  end
130
130
 
131
- documentation "Update id of #{model} to be provided data" do
132
- payload "Whatever JSON you want updated to be. Needs to be valid JSON"
133
- response "Data in #{model}"
134
- status 204
135
- status 404
136
- end
137
131
  put "/#{model.downcase}/:id" do |id|
138
- response["Access-Control-Allow-Origin"] = "*"
139
- SchemalessRestApi.logger.info "PUT #{request.fullpath}"
140
132
  data = JSON.parse(request.body.read)
141
133
  if ENV["mongodb"]
142
134
  results = MongoClient.find(model, id)
@@ -151,13 +143,7 @@ class RestServer < Sinatra::Base
151
143
  204
152
144
  end
153
145
 
154
- documentation "Update id of #{model} to be deleted" do
155
- response "Empty"
156
- status 204
157
- end
158
146
  delete "/#{model.downcase}/:id" do |id|
159
- response["Access-Control-Allow-Origin"] = "*"
160
- SchemalessRestApi.logger.info "DEL #{request.fullpath}"
161
147
  if ENV["mongodb"]
162
148
  results = MongoClient.find(model, id)
163
149
  return not_have(id) unless results.first
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: true
4
+
5
+ module ServerUtils
6
+ def log(messages)
7
+ if SchemalessRestApi.log_type == :ougai
8
+ log_msg = {
9
+ method: request.request_method,
10
+ path: request.fullpath,
11
+ correlationId: @request_id
12
+ }
13
+ messages.each do |key, value|
14
+ log_msg[key] = value
15
+ end
16
+ SchemalessRestApi.logger.info(log_msg)
17
+ else
18
+ message = messages.values.join(", ")
19
+ SchemalessRestApi.logger.info "#{message}, #{request.request_method} #{request.fullpath}, CorrelationId: #{@request_id}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ html {
2
+ box-sizing: border-box;
3
+ overflow: -moz-scrollbars-vertical;
4
+ overflow-y: scroll;
5
+ }
6
+
7
+ *,
8
+ *:before,
9
+ *:after {
10
+ box-sizing: inherit;
11
+ }
12
+
13
+ body {
14
+ margin: 0;
15
+ background: #fafafa;
16
+ }
@@ -0,0 +1,19 @@
1
+ window.onload = function() {
2
+ //<editor-fold desc="Changeable Configuration Block">
3
+
4
+ window.ui = SwaggerUIBundle({
5
+ url: "./swagger.json",
6
+ dom_id: '#swagger-ui',
7
+ deepLinking: true,
8
+ presets: [
9
+ SwaggerUIBundle.presets.apis,
10
+ SwaggerUIStandalonePreset
11
+ ],
12
+ plugins: [
13
+ SwaggerUIBundle.plugins.DownloadUrl
14
+ ],
15
+ layout: "StandaloneLayout"
16
+ });
17
+
18
+ //</editor-fold>
19
+ };