blest 0.0.1 → 0.1.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 +64 -111
  3. data/lib/blest.rb +808 -143
  4. data/spec/blest_spec.rb +219 -0
  5. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0a8f112cb397ac2725175231766a0ca838e9ce898180cfc8be6e59e7fa498b8
4
- data.tar.gz: b9f91cdfb82e5058d889fd6abddc8f14248c567567a3cb0acbd673d04b99f84c
3
+ metadata.gz: 6307985d2fcaa8aa558a9d6fa55bd61787de23accd0d762d12843cf1202784c8
4
+ data.tar.gz: b58fc887beb5b6312f14f7332daab521b37baa037750eb3b1b406191160ae0d1
5
5
  SHA512:
6
- metadata.gz: 7fc3d8ae042c5b9dc96cb9fda9edeada1e34c26d1d08e890e72359c74f675e7c874b3c71ec78e4c056a8aaa886081be3374d87a46e22f86fd8689019149a9c8f
7
- data.tar.gz: a862d3210e033fdf7b9d71b6b65b710a169955b49804df64aacfe0aacc73486f28e42a5dbf37994e66fa7a66ade5a39bbb2ecb5984941f5cf2c7284cc87308a8
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 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
 
@@ -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
- <!-- ## Installation
18
+ ## Installation
19
19
 
20
- Install BLEST Python from PyPI.
20
+ Install BLEST Ruby from Rubygems.
21
21
 
22
22
  ```bash
23
- python3 -m pip install blest
24
- ``` -->
23
+ gem install blest
24
+ ```
25
25
 
26
26
  ## Usage
27
27
 
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
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 'socket'
36
- require 'json'
37
- require './blest.rb'
31
+ require 'blest'
38
32
 
39
- server = TCPServer.new('localhost', 8080)
33
+ app = Blest.new(timeout: 1000, port: 8080, host: 'localhost', cors: 'http://localhost:3000')
40
34
 
41
35
  # Create some middleware (optional)
42
- auth_middleware = ->(params, context) {
43
- if params[:name].present?
44
- context[:user] = {
45
- name: params[:name]
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
- greet_controller = ->(params, context) {
48
+ app.route('greet') do |params, context|
55
49
  {
56
- greeting: "Hi, #{context[:user][:name]}!"
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
- ### create_http_server
58
+ ### Router
59
+
60
+ The following example uses Sinatra.
130
61
 
131
62
  ```ruby
132
- require 'socket'
63
+ require 'sinatra'
133
64
  require 'json'
134
- require './blest.rb'
65
+ require 'blest'
66
+
67
+ # Instantiate the Router
68
+ router = Router.new(timeout: 1000)
135
69
 
136
70
  # Create some middleware (optional)
137
- auth_middleware = ->(params, context) {
138
- if params[:name].present?
139
- context[:user] = {
140
- name: params[:name]
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
- greet_controller = ->(params, context) {
83
+ router.route('greet') do |params, context|
150
84
  {
151
- greeting: "Hi, #{context[:user][:name]}!"
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
- # Create a request handler
161
- handler = create_request_handler(router)
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
- # Create the server
164
- server = create_http_server(handler, { port: 8080 })
103
+ ### HttpClient
165
104
 
166
- # Run the server
167
- server.()
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).