schemaless_rest_api 0.3.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|