schemaless_rest_api 0.3.1 → 0.3.3
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 +4 -4
- data/lib/schemaless_rest_api/mongo_client.rb +19 -15
- data/lib/schemaless_rest_api/rest_server.rb +41 -15
- data/lib/schemaless_rest_api/version.rb +3 -1
- data/lib/schemaless_rest_api.rb +26 -15
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 983c38081a6ee3d08a9d75b2e9425899329d1df050974088a5aac6eb21d924e5
|
4
|
+
data.tar.gz: 2ed42db41c915a2106da88ac4d9179ea5bc55a8a594ec47dd0bc89f93f3ca8ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ceafb7b6ed5b550dd7aae21ab964ec181ccb2b82221aaaf931596c5a379bbd4a4881eecda5b9896fb4179adb8ab6f37197b320cf6018213fda5979e42c266474
|
7
|
+
data.tar.gz: 276bb03925b12bc91bebeee8344b863033b237b336880a799ee7f309a90e27d4d8f86ab0a3c4a532e2e23cc001eacf1c9d9b14d6d3dd8991c694edad4407c449
|
@@ -1,4 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "mongo"
|
2
|
+
|
3
|
+
# typed: false - MongoClient new
|
2
4
|
|
3
5
|
module MongoClient
|
4
6
|
class << self
|
@@ -7,11 +9,11 @@ module MongoClient
|
|
7
9
|
|
8
10
|
def insert(model, data, id)
|
9
11
|
collection = MongoClient.client[model]
|
10
|
-
collection.insert_one({ id: id, **data})
|
12
|
+
collection.insert_one({ id: id, **data })
|
11
13
|
end
|
12
14
|
|
13
15
|
def find(model, id)
|
14
|
-
find_all(model, { id: id }
|
16
|
+
find_all(model, { id: id })
|
15
17
|
end
|
16
18
|
|
17
19
|
def get_all(model)
|
@@ -24,7 +26,7 @@ module MongoClient
|
|
24
26
|
|
25
27
|
def find_all(model, query)
|
26
28
|
collection = MongoClient.client[model]
|
27
|
-
collection.find(
|
29
|
+
collection.find(query).collect do |match|
|
28
30
|
match.delete("_id")
|
29
31
|
match
|
30
32
|
end
|
@@ -32,7 +34,7 @@ module MongoClient
|
|
32
34
|
|
33
35
|
def update(model, id, data)
|
34
36
|
collection = MongoClient.client[model]
|
35
|
-
collection.update_one({ id: id }, { id: id, **data})
|
37
|
+
collection.update_one({ id: id }, { id: id, **data })
|
36
38
|
end
|
37
39
|
|
38
40
|
def delete(model, id)
|
@@ -42,13 +44,15 @@ module MongoClient
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
if ENV[
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
MongoClient.client = if ENV["mongo_root_password"]
|
48
|
+
Mongo::Client.new(
|
49
|
+
["#{ENV["mongodb"]}:27017"],
|
50
|
+
database: "api", password: ENV["mongo_root_password"],
|
51
|
+
user: "root"
|
52
|
+
)
|
53
|
+
else
|
54
|
+
Mongo::Client.new(
|
55
|
+
["#{ENV["mongodb"]}:27017"],
|
56
|
+
database: "api"
|
57
|
+
)
|
58
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "sinatra"
|
4
|
-
require
|
4
|
+
require "docdsl"
|
5
5
|
require "puma"
|
6
|
-
require
|
6
|
+
require "route_downcaser"
|
7
7
|
|
8
|
+
# Server with endpoints generated based on Entities with CRUD operations for them
|
8
9
|
class RestServer < Sinatra::Base
|
9
10
|
set :server, :puma
|
10
11
|
enable :logging if ENV["debug"] == "true"
|
@@ -35,8 +36,8 @@ class RestServer < Sinatra::Base
|
|
35
36
|
end
|
36
37
|
get "/" do
|
37
38
|
summary = { models: Entities.models.keys.to_s,
|
38
|
-
docs_url:
|
39
|
-
summary[:db] = MongoClient.client.summary.to_s if ENV[
|
39
|
+
docs_url: "<a href=/docs>/docs</a>" }
|
40
|
+
summary[:db] = MongoClient.client.summary.to_s if ENV["mongodb"]
|
40
41
|
JSON.generate(summary)
|
41
42
|
rescue Exception => e
|
42
43
|
[500, e.message]
|
@@ -49,15 +50,16 @@ class RestServer < Sinatra::Base
|
|
49
50
|
status 201
|
50
51
|
end
|
51
52
|
post "/#{model.downcase}" do
|
53
|
+
response["Access-Control-Allow-Origin"] = "*"
|
52
54
|
data = JSON.parse(request.body.read)
|
53
|
-
id =
|
54
|
-
if
|
55
|
-
id = data[
|
55
|
+
id = ""
|
56
|
+
if data["id"]
|
57
|
+
id = data["id"].to_s
|
56
58
|
else
|
57
59
|
id = SecureRandom.uuid
|
58
|
-
data[
|
60
|
+
data["id"] = id
|
59
61
|
end
|
60
|
-
if ENV[
|
62
|
+
if ENV["mongodb"]
|
61
63
|
MongoClient.insert(model, data, id)
|
62
64
|
else
|
63
65
|
Entities.models[model][id] = data
|
@@ -65,14 +67,22 @@ class RestServer < Sinatra::Base
|
|
65
67
|
[201, JSON.generate({ id: id })]
|
66
68
|
end
|
67
69
|
|
70
|
+
options "/#{model.downcase}" do
|
71
|
+
response["Allow"] = "*"
|
72
|
+
response["Access-Control-Allow-Origin"] = "*"
|
73
|
+
response["Access-Control-Allow-Methods"] = "*"
|
74
|
+
response["Access-Control-Allow-Headers"] = "*"
|
75
|
+
end
|
76
|
+
|
68
77
|
documentation "Retrieve all instances of #{model} or filtered by query param" do
|
69
78
|
response "Data in #{model}"
|
70
79
|
query_param :key_to_search_in_data, "Value of key"
|
71
80
|
status 200
|
72
81
|
end
|
73
82
|
get "/#{model.downcase}" do
|
74
|
-
|
75
|
-
|
83
|
+
response["Access-Control-Allow-Origin"] = "*"
|
84
|
+
SchemalessRestApi.logger.info request.fullpath
|
85
|
+
if ENV["mongodb"]
|
76
86
|
if params == {}
|
77
87
|
JSON.generate(MongoClient.get_all(model))
|
78
88
|
else
|
@@ -81,7 +91,10 @@ class RestServer < Sinatra::Base
|
|
81
91
|
else
|
82
92
|
return JSON.generate(Entities.models[model].values) if params == {}
|
83
93
|
|
84
|
-
Entities.models[model].values.find_all
|
94
|
+
matching_values = Entities.models[model].values.find_all do |val|
|
95
|
+
val[params.keys[0]].to_s == params.values[0]
|
96
|
+
end
|
97
|
+
return JSON.generate(matching_values)
|
85
98
|
end
|
86
99
|
rescue Exception => e
|
87
100
|
[404, "Nothing found using #{params}. Only first param considered. #{e.message}"]
|
@@ -93,10 +106,12 @@ class RestServer < Sinatra::Base
|
|
93
106
|
status 404
|
94
107
|
end
|
95
108
|
get "/#{model.downcase}/:id" do |id|
|
109
|
+
response["Access-Control-Allow-Origin"] = "*"
|
96
110
|
puts request.path.downcase
|
97
|
-
if ENV[
|
111
|
+
if ENV["mongodb"]
|
98
112
|
results = MongoClient.find(model, id)
|
99
113
|
return not_have(id) unless results.first
|
114
|
+
|
100
115
|
JSON.generate(results.first)
|
101
116
|
else
|
102
117
|
return not_have(id) unless has_id?(model, id)
|
@@ -105,6 +120,13 @@ class RestServer < Sinatra::Base
|
|
105
120
|
end
|
106
121
|
end
|
107
122
|
|
123
|
+
options "/#{model.downcase}/:id" do
|
124
|
+
response["Allow"] = "*"
|
125
|
+
response["Access-Control-Allow-Origin"] = "*"
|
126
|
+
response["Access-Control-Allow-Methods"] = "*"
|
127
|
+
response["Access-Control-Allow-Headers"] = "*"
|
128
|
+
end
|
129
|
+
|
108
130
|
documentation "Update id of #{model} to be provided data" do
|
109
131
|
payload "Whatever JSON you want updated to be. Needs to be valid JSON"
|
110
132
|
response "Data in #{model}"
|
@@ -112,11 +134,13 @@ class RestServer < Sinatra::Base
|
|
112
134
|
status 404
|
113
135
|
end
|
114
136
|
put "/#{model.downcase}/:id" do |id|
|
137
|
+
response["Access-Control-Allow-Origin"] = "*"
|
115
138
|
puts request.path.downcase
|
116
139
|
data = JSON.parse(request.body.read)
|
117
|
-
if ENV[
|
140
|
+
if ENV["mongodb"]
|
118
141
|
results = MongoClient.find(model, id)
|
119
142
|
return not_have(id) unless results.first
|
143
|
+
|
120
144
|
MongoClient.update(model, id, data)
|
121
145
|
else
|
122
146
|
return not_have(id) unless has_id?(model, id)
|
@@ -131,10 +155,12 @@ class RestServer < Sinatra::Base
|
|
131
155
|
status 204
|
132
156
|
end
|
133
157
|
delete "/#{model.downcase}/:id" do |id|
|
158
|
+
response["Access-Control-Allow-Origin"] = "*"
|
134
159
|
puts request.path.downcase
|
135
|
-
if ENV[
|
160
|
+
if ENV["mongodb"]
|
136
161
|
results = MongoClient.find(model, id)
|
137
162
|
return not_have(id) unless results.first
|
163
|
+
|
138
164
|
MongoClient.delete(model, id)
|
139
165
|
else
|
140
166
|
return not_have(id) unless has_id?(model, id)
|
data/lib/schemaless_rest_api.rb
CHANGED
@@ -1,28 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# typed: true
|
4
|
+
|
3
5
|
require_relative "schemaless_rest_api/version"
|
4
6
|
require_relative "schemaless_rest_api/entities"
|
5
7
|
|
8
|
+
require "logger"
|
9
|
+
|
6
10
|
require "json"
|
7
11
|
require "securerandom"
|
8
12
|
|
13
|
+
# Global params for Schemalass REST API
|
14
|
+
module SchemalessRestApi
|
15
|
+
@logger = Logger.new($stdout)
|
16
|
+
class << self
|
17
|
+
# @return Logger
|
18
|
+
attr_accessor :logger
|
19
|
+
end
|
20
|
+
|
21
|
+
class Error < StandardError; end
|
22
|
+
end
|
23
|
+
|
9
24
|
def models_env_not_set
|
10
|
-
!ENV["models"] || ENV["models"].empty?
|
25
|
+
!ENV["models"] || T.must(ENV["models"]).empty?
|
11
26
|
end
|
12
27
|
|
13
28
|
def extract_models
|
14
|
-
return [] if
|
15
|
-
|
29
|
+
return [] if !Entities.models.empty? && models_env_not_set
|
30
|
+
|
16
31
|
error_msg = "Make 'models' environment variable an array (e.g ['model1', 'model2'])"
|
17
32
|
raise "Please set 'models' ENV variable or create 'db.json'. #{error_msg}" if ENV["models"].nil?
|
18
33
|
|
19
|
-
models = eval(ENV["models"])
|
34
|
+
models = eval(T.must(ENV["models"])) # rubocop:disable Security/Eval
|
20
35
|
raise error_msg unless models.is_a? Array
|
21
36
|
|
22
37
|
models
|
23
38
|
end
|
24
39
|
|
25
|
-
SEED_FILE =
|
40
|
+
SEED_FILE = "db.json"
|
26
41
|
|
27
42
|
if File.exist? SEED_FILE
|
28
43
|
puts "Seeding db based on '#{SEED_FILE}'"
|
@@ -31,10 +46,11 @@ if File.exist? SEED_FILE
|
|
31
46
|
Entities.models[entity.to_sym] = {} unless Entities.models[entity.to_sym]
|
32
47
|
if values.is_a? Array
|
33
48
|
values.each do |value|
|
34
|
-
next unless value[
|
35
|
-
|
49
|
+
next unless value["id"]
|
50
|
+
|
51
|
+
Entities.models[entity.to_sym][value["id"].to_s] = value
|
36
52
|
end
|
37
|
-
else
|
53
|
+
else
|
38
54
|
puts "Entity 'entity' doesn't have array, skipping"
|
39
55
|
end
|
40
56
|
end
|
@@ -46,15 +62,10 @@ end
|
|
46
62
|
|
47
63
|
puts "Modelling #{Entities.models.keys}"
|
48
64
|
|
49
|
-
if ENV[
|
50
|
-
require_relative
|
65
|
+
if ENV["mongodb"]
|
66
|
+
require_relative "schemaless_rest_api/mongo_client"
|
51
67
|
else
|
52
68
|
puts "[INFO] Using in memory storage. Pass in 'mongodb' ENV variable to store
|
53
69
|
in db"
|
54
70
|
end
|
55
71
|
require_relative "schemaless_rest_api/rest_server"
|
56
|
-
|
57
|
-
module SchemalessRestApi
|
58
|
-
class Error < StandardError; end
|
59
|
-
# Your code goes here...
|
60
|
-
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schemaless_rest_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Garratt
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: mongo
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: puma
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rackup
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: route_downcaser
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: sinatra
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: sinatra-docdsl
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: thor
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|