blest 0.0.1 → 0.1.0
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/README.md +64 -111
- data/lib/blest.rb +808 -143
- data/spec/blest_spec.rb +219 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6307985d2fcaa8aa558a9d6fa55bd61787de23accd0d762d12843cf1202784c8
|
4
|
+
data.tar.gz: b58fc887beb5b6312f14f7332daab521b37baa037750eb3b1b406191160ae0d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f0b5c80b2ae39259d5386c60a7a27deb6b04dc35a5162c30be64056d10581de3b6a6ee47cd800e27f4e4cac1f52a6cb692b47abbda7533ed48dc85c3eafe403
|
7
|
+
data.tar.gz: 964ab1acc3ca2db12a2918bb141efa3f254438c095b47c7e81313c4b5140d7a10b13712b3a4773e6fa1b76158ccc75dffa2af591df45fdb55a767278ea72e470
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
The Ruby reference implementation of BLEST (Batch-able, Lightweight, Encrypted State Transfer), an improved communication protocol for web APIs which leverages JSON, supports request batching and selective returns, and provides a modern alternative to REST.
|
4
4
|
|
5
|
-
To learn more about BLEST, please
|
5
|
+
To learn more about BLEST, please visit the website: https://blest.jhunt.dev
|
6
6
|
|
7
7
|
For a front-end implementation in React, please visit https://github.com/jhuntdev/blest-react
|
8
8
|
|
@@ -15,158 +15,111 @@ For a front-end implementation in React, please visit https://github.com/jhuntde
|
|
15
15
|
- Single Endpoint - Reduce complexity and improve data privacy
|
16
16
|
- Fully Encrypted - Improve data privacy
|
17
17
|
|
18
|
-
|
18
|
+
## Installation
|
19
19
|
|
20
|
-
Install BLEST
|
20
|
+
Install BLEST Ruby from Rubygems.
|
21
21
|
|
22
22
|
```bash
|
23
|
-
|
24
|
-
```
|
23
|
+
gem install blest
|
24
|
+
```
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
<!-- Use the `create_http_client` function to create a BLEST HTTP client. -->
|
31
|
-
|
32
|
-
### create_request_handler
|
28
|
+
This core class of this library has an interface somewhat similar to Sinatra. It also provides a `Router` class with a `handle` method for use in an existing Ruby API and an `HttpClient` class with a `request` method for making BLEST HTTP requests.
|
33
29
|
|
34
30
|
```ruby
|
35
|
-
require '
|
36
|
-
require 'json'
|
37
|
-
require './blest.rb'
|
31
|
+
require 'blest'
|
38
32
|
|
39
|
-
|
33
|
+
app = Blest.new(timeout: 1000, port: 8080, host: 'localhost', cors: 'http://localhost:3000')
|
40
34
|
|
41
35
|
# Create some middleware (optional)
|
42
|
-
|
43
|
-
if params[
|
44
|
-
context[
|
45
|
-
name: params[
|
36
|
+
app.before do |params, context|
|
37
|
+
if params['name'].present?
|
38
|
+
context['user'] = {
|
39
|
+
name: params['name']
|
46
40
|
}
|
47
41
|
nil
|
48
42
|
else
|
49
43
|
raise RuntimeError, "Unauthorized"
|
50
44
|
end
|
51
|
-
|
45
|
+
end
|
52
46
|
|
53
47
|
# Create a route controller
|
54
|
-
|
48
|
+
app.route('greet') do |params, context|
|
55
49
|
{
|
56
|
-
greeting: "Hi, #{context[
|
50
|
+
greeting: "Hi, #{context['user']['name']}!"
|
57
51
|
}
|
58
|
-
}
|
59
|
-
|
60
|
-
# Create a router
|
61
|
-
router = {
|
62
|
-
greet: [auth_middleware, greet_controller]
|
63
|
-
}
|
64
|
-
|
65
|
-
# Create a request handler
|
66
|
-
handler = create_request_handler(router)
|
67
|
-
|
68
|
-
puts "Server listening on port 8080"
|
69
|
-
|
70
|
-
loop do
|
71
|
-
|
72
|
-
client = server.accept
|
73
|
-
|
74
|
-
request = client.gets
|
75
|
-
if request.nil?
|
76
|
-
client.close
|
77
|
-
else
|
78
|
-
|
79
|
-
method, path, _ = request.split(' ')
|
80
|
-
|
81
|
-
if method != 'POST'
|
82
|
-
client.puts "HTTP/1.1 405 Method Not Allowed"
|
83
|
-
client.puts "\r\n"
|
84
|
-
elsif path != '/'
|
85
|
-
client.puts "HTTP/1.1 404 Not Found"
|
86
|
-
client.puts "\r\n"
|
87
|
-
else
|
88
|
-
content_length = 0
|
89
|
-
while line = client.gets
|
90
|
-
break if line == "\r\n"
|
91
|
-
content_length = line.split(': ')[1].to_i if line.start_with?('Content-Length')
|
92
|
-
end
|
93
|
-
|
94
|
-
body = client.read(content_length)
|
95
|
-
data = JSON.parse(body)
|
96
|
-
|
97
|
-
context = {
|
98
|
-
headers: request.headers
|
99
|
-
}
|
100
|
-
|
101
|
-
# Use the request handler]
|
102
|
-
result, error = handler.(data, context)
|
103
|
-
|
104
|
-
if error
|
105
|
-
response = error.to_json
|
106
|
-
client.puts "HTTP/1.1 500 Internal Server Error"
|
107
|
-
client.puts "Content-Type: application/json"
|
108
|
-
client.puts "Content-Length: #{response.bytesize}"
|
109
|
-
client.puts "\r\n"
|
110
|
-
client.puts response
|
111
|
-
elsif result
|
112
|
-
response = result.to_json
|
113
|
-
client.puts "HTTP/1.1 200 OK"
|
114
|
-
client.puts "Content-Type: application/json"
|
115
|
-
client.puts "Content-Length: #{response.bytesize}"
|
116
|
-
client.puts "\r\n"
|
117
|
-
client.puts response
|
118
|
-
else
|
119
|
-
client.puts "HTTP/1.1 204 No Content"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
client.close
|
124
|
-
|
125
|
-
end
|
126
52
|
end
|
53
|
+
|
54
|
+
# Start the server
|
55
|
+
app.listen
|
127
56
|
```
|
128
57
|
|
129
|
-
###
|
58
|
+
### Router
|
59
|
+
|
60
|
+
The following example uses Sinatra.
|
130
61
|
|
131
62
|
```ruby
|
132
|
-
require '
|
63
|
+
require 'sinatra'
|
133
64
|
require 'json'
|
134
|
-
require '
|
65
|
+
require 'blest'
|
66
|
+
|
67
|
+
# Instantiate the Router
|
68
|
+
router = Router.new(timeout: 1000)
|
135
69
|
|
136
70
|
# Create some middleware (optional)
|
137
|
-
|
138
|
-
if params[
|
139
|
-
context[
|
140
|
-
name: params[
|
71
|
+
router.before do |params, context|
|
72
|
+
if params['name'].present?
|
73
|
+
context['user'] = {
|
74
|
+
name: params['name']
|
141
75
|
}
|
142
76
|
nil
|
143
77
|
else
|
144
78
|
raise RuntimeError, "Unauthorized"
|
145
79
|
end
|
146
|
-
|
80
|
+
end
|
147
81
|
|
148
82
|
# Create a route controller
|
149
|
-
|
83
|
+
router.route('greet') do |params, context|
|
150
84
|
{
|
151
|
-
greeting: "Hi, #{context[
|
85
|
+
greeting: "Hi, #{context['user']['name']}!"
|
152
86
|
}
|
153
|
-
|
154
|
-
|
155
|
-
# Create a router
|
156
|
-
router = {
|
157
|
-
greet: [auth_middleware, greet_controller]
|
158
|
-
}
|
87
|
+
end
|
159
88
|
|
160
|
-
#
|
161
|
-
|
89
|
+
# Handle BLEST requests
|
90
|
+
post '/' do
|
91
|
+
json_body = JSON.parse(request.body.read)
|
92
|
+
headers = request.env.select { |k, _| k.start_with?('HTTP_') }
|
93
|
+
result, error = router.handle.call(json_body, { 'headers' => headers })
|
94
|
+
content_type :json
|
95
|
+
if error
|
96
|
+
raise Sinatra::Error.new(error.status || 500, error)
|
97
|
+
else
|
98
|
+
result
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
162
102
|
|
163
|
-
|
164
|
-
server = create_http_server(handler, { port: 8080 })
|
103
|
+
### HttpClient
|
165
104
|
|
166
|
-
|
167
|
-
|
105
|
+
```ruby
|
106
|
+
require 'blest'
|
107
|
+
|
108
|
+
# Create a client
|
109
|
+
client = HttpClient.new('http://localhost:8080', max_batch_size = 25, buffer_delay = 10, headers = {
|
110
|
+
'Authorization': 'Bearer token'
|
111
|
+
})
|
112
|
+
|
113
|
+
# Send a request
|
114
|
+
begin
|
115
|
+
result = client.request('greet', { 'name': 'Steve' }, ['greeting']).value
|
116
|
+
# Do something with the result
|
117
|
+
rescue => error
|
118
|
+
# Do something in case of error
|
119
|
+
end
|
168
120
|
```
|
169
121
|
|
122
|
+
|
170
123
|
## License
|
171
124
|
|
172
125
|
This project is licensed under the [MIT License](LICENSE).
|