blest 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -99
  3. data/lib/blest.rb +811 -143
  4. data/spec/blest_spec.rb +220 -0
  5. metadata +10 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cbe0f3613fd73841d959cad671fb7ec368ff5de50a2e5e874048871070d70b5
4
- data.tar.gz: 209e015fa2bd51a03476ab597bbc4c4109037cfea52b79904a27f2a54fc1b368
3
+ metadata.gz: c4f44d941bb783457e67fa52ada69792f5f645a76bac399165d59c73f4ba7b4b
4
+ data.tar.gz: 8f7ee45d396ae4cab3c8178f1bef7e6605612efb94e259cbb35bcd3da842e347
5
5
  SHA512:
6
- metadata.gz: 8d9a2f9db5673835a9d0187374b52be72dd596a5ec9a3744a164cb6aecbefddfa0d96b3cd23bce63a706dd39fcdcde0e2c5f0231cd71086208d34820280b1d05
7
- data.tar.gz: e5d92953980bfe4a4e9a0d9c6c98db057cb5f5067af87680b2e83b4dc37df7ac52c5c3042697f63e9652dbefd3db2b0740f7c124b1837d330accd4b0360bfd57
6
+ metadata.gz: aecfa3005a9a29bcfd4b4f501710a0f8a49251ff7fc62f4043bfe8e5b0e7f6c8e2ddbb09df2ae14c08bc7617a09ab08d84ed52d9023272bd9bb05dabd1fb8e41
7
+ data.tar.gz: 2855b895975b23f418e0e084ecd3d15bd8df43764a896aca1f8fa5788d21e74ab7fb5ff5fdc4bbcd79a074dff7ce2f14bb3a10ee4e497d8ef1d63b1a645066c3
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # BLEST Ruby
2
2
 
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.
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 by default, and provides a modern alternative to REST.
4
4
 
5
- To learn more about BLEST, please refer to the white paper: https://jhunt.dev/BLEST%20White%20Paper.pdf
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
 
@@ -10,9 +10,8 @@ For a front-end implementation in React, please visit https://github.com/jhuntde
10
10
 
11
11
  - Built on JSON - Reduce parsing time and overhead
12
12
  - Request Batching - Save bandwidth and reduce load times
13
- - Compact Payloads - Save more bandwidth
14
- - Selective Returns - Save even more bandwidth
15
- - Single Endpoint - Reduce complexity and improve data privacy
13
+ - Compact Payloads - Save even more bandwidth
14
+ - Single Endpoint - Reduce complexity and facilitate introspection
16
15
  - Fully Encrypted - Improve data privacy
17
16
 
18
17
  ## Installation
@@ -25,139 +24,101 @@ gem install blest
25
24
 
26
25
  ## Usage
27
26
 
28
- Use the `create_request_handler` function to create a request handler suitable for use in an existing Python application. Use the `create_http_server` function to create a standalone HTTP server for your request handler.
29
-
30
- <!-- Use the `create_http_client` function to create a BLEST HTTP client. -->
31
-
32
- ### create_request_handler
27
+ The `Blest` class of this library has an interface 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
28
 
34
29
  ```ruby
35
- require 'webrick'
36
- require 'json'
37
30
  require 'blest'
38
31
 
32
+ app = Blest.new(timeout: 1000, port: 8080, host: 'localhost', cors: 'http://localhost:3000')
33
+
39
34
  # Create some middleware (optional)
40
- auth_middleware = ->(params, context) {
41
- if params[:name].present?
42
- context[:user] = {
43
- name: params[:name]
35
+ app.before do |body, context|
36
+ if context.dig('headers', 'auth') == 'myToken'?
37
+ context['user'] = {
38
+ # user info for example
44
39
  }
45
40
  nil
46
41
  else
47
42
  raise RuntimeError, "Unauthorized"
48
43
  end
49
- }
44
+ end
50
45
 
51
46
  # Create a route controller
52
- greet_controller = ->(params, context) {
47
+ app.route('greet') do |body, context|
53
48
  {
54
- greeting: "Hi, #{context[:user][:name]}!"
49
+ greeting: "Hi, #{body['name']}!"
55
50
  }
56
- }
57
-
58
- # Create a router
59
- router = {
60
- greet: [auth_middleware, greet_controller]
61
- }
62
-
63
- # Create a request handler
64
- handler = create_request_handler(router)
65
-
66
- class HttpRequestHandler < WEBrick::HTTPServlet::AbstractServlet
67
- def do_OPTIONS(request, response)
68
- response.status = 200
69
- response['Access-Control-Allow-Origin'] = '*'
70
- response['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
71
- response['Access-Control-Allow-Headers'] = 'Content-Type'
72
- end
73
-
74
- def do_POST(request, response)
75
- response['Content-Type'] = 'application/json'
76
- response['Access-Control-Allow-Origin'] = '*'
77
-
78
- # Parse JSON body
79
- begin
80
- payload = JSON.parse(request.body)
81
-
82
- # Define the request context
83
- context = {
84
- headers: request.headers
85
- }
86
-
87
- # Use the request handler
88
- result, error = handler.(payload, context)
89
-
90
- # Do something with the result or error
91
- if error
92
- response_body = error.to_json
93
- response.status = 500
94
- response.body = response_body
95
- elsif result
96
- response_body = result.to_json
97
- response.status = 200
98
- response.body = response_body
99
- else
100
- response.status = 204
101
- end
102
-
103
- rescue JSON::ParserError
104
- response.status = 400
105
- response.body = { message: 'Invalid JSON' }.to_json
106
- end
107
- end
108
51
  end
109
52
 
110
- # Create WEBrick server
111
- server = WEBrick::HTTPServer.new(Port: 8000)
112
-
113
- # Mount custom request handler
114
- server.mount('/', HttpRequestHandler)
115
-
116
- trap('INT') { server.shutdown }
117
-
118
53
  # Start the server
119
- server.start
54
+ app.listen
120
55
  ```
121
56
 
122
- ### create_http_server
57
+ ### Router
58
+
59
+ The following example uses Sinatra.
123
60
 
124
61
  ```ruby
62
+ require 'sinatra'
63
+ require 'json'
125
64
  require 'blest'
126
65
 
66
+ # Instantiate the Router
67
+ router = Router.new(timeout: 1000)
68
+
127
69
  # Create some middleware (optional)
128
- auth_middleware = ->(params, context) {
129
- if params[:name].present?
130
- context[:user] = {
131
- name: params[:name]
70
+ router.before do |body, context|
71
+ if context.dig('headers', 'auth') == 'myToken'?
72
+ context['user'] = {
73
+ # user info for example
132
74
  }
133
75
  nil
134
76
  else
135
77
  raise RuntimeError, "Unauthorized"
136
78
  end
137
- }
79
+ end
138
80
 
139
81
  # Create a route controller
140
- greet_controller = ->(params, context) {
82
+ router.route('greet') do |body, context|
141
83
  {
142
- greeting: "Hi, #{context[:user][:name]}!"
84
+ greeting: "Hi, #{body['name']}!"
143
85
  }
144
- }
86
+ end
145
87
 
146
- # Create a router
147
- router = {
148
- greet: [auth_middleware, greet_controller]
149
- }
88
+ # Handle BLEST requests
89
+ post '/' do
90
+ json_body = JSON.parse(request.body.read)
91
+ headers = request.env.select { |k, _| k.start_with?('HTTP_') }
92
+ result, error = router.handle.call(json_body, { 'headers' => headers })
93
+ content_type :json
94
+ if error
95
+ raise Sinatra::Error.new(error.status || 500, error)
96
+ else
97
+ result
98
+ end
99
+ end
100
+ ```
150
101
 
151
- # Create a request handler
152
- handler = create_request_handler(router)
102
+ ### HttpClient
153
103
 
154
- # Create the server
155
- server = create_http_server(handler, { port: 8080 })
104
+ ```ruby
105
+ require 'blest'
156
106
 
157
- # Run the server
158
- server.()
107
+ # Create a client
108
+ client = HttpClient.new('http://localhost:8080', max_batch_size = 25, buffer_delay = 10, http_headers = {
109
+ 'Authorization': 'Bearer token'
110
+ })
111
+
112
+ # Send a request
113
+ begin
114
+ result = client.request('greet', { 'name': 'Steve' }, ['greeting']).value
115
+ # Do something with the result
116
+ rescue => error
117
+ # Do something in case of error
118
+ end
159
119
  ```
160
120
 
121
+
161
122
  ## License
162
123
 
163
124
  This project is licensed under the [MIT License](LICENSE).