broker/README.md

152 lines
4.6 KiB
Markdown
Raw Normal View History

2020-01-01 20:04:51 +00:00
## Broker - Real-time Zero-Code API Server
2019-12-16 18:04:14 +00:00
2020-01-01 05:09:38 +00:00
[![crates.io](https://meritbadge.herokuapp.com/broker)](https://crates.io/crates/broker)
2019-12-31 20:30:58 +00:00
2020-01-01 02:28:56 +00:00
### Purpose
2020-01-01 20:04:51 +00:00
The purpose of this library is to be your real-time zero-code API server.
2020-01-01 02:28:56 +00:00
2020-01-01 20:04:51 +00:00
Broker is a SSE message broker that requires you write no backend code to have a full real-time API.
Broker is born from the need that rather than building a complex REST API with web-sockets and a SQL database to provide reactive web forms (like for React) there must be a simpler way.
2020-01-01 02:28:56 +00:00
2020-01-01 05:09:38 +00:00
Broker follows an insert-only/publish/subscribe paradigm rather than a REST CRUD paradigm.
2020-01-01 02:28:56 +00:00
2020-01-04 09:03:18 +00:00
2020-01-01 06:35:44 +00:00
### How it works
2020-01-07 19:58:46 +00:00
In Broker you create a user, login, then insert an event with its data, a collection_id, and a timestamp. Broker publishes the event when the timestamp is reached to the event stream via SSE. Broker keeps all events its database that can be viewed in collections (by collection_id). Broker can also cancel future events.
2020-01-01 02:28:56 +00:00
2020-01-06 07:24:24 +00:00
When the client first subscribes to the SSE connection all the latest events and data is sent to the client. Combined with sending the latest event via SSE when subscribed negates the necessity to do any GET API requests in the lifecycle of an event.
2020-01-01 02:28:56 +00:00
The side-effect of this system is that the latest event is the schema. Old events are saved in the database and are not changed but the latest event is the schema for the front-end. This is pure NoSQL as the backend is agnostic to the event data.
2020-01-04 09:03:18 +00:00
#### API
2020-01-07 19:58:46 +00:00
##### Step 1 - create a user
2020-01-06 10:44:37 +00:00
```html
/users
```
- public endpoint
2020-01-06 07:24:24 +00:00
- POST JSON to create a user
```json
{"username":{...}, "password":{...}, "info":{...}}
```
- where {...} is for username and string, password a string, and info any JSON you want
2020-01-07 00:22:22 +00:00
will return
```json
{"id":{...}}
```
- where {...} is the uuid (string) of the user
2020-01-07 19:58:46 +00:00
##### Step 2 - login with the user
2020-01-06 10:44:37 +00:00
```html
/login
```
- public endpoint
2020-01-06 07:24:24 +00:00
- POST JSON to login
```json
{"username":{...}, "password":{...}}
```
- where {...} is for username a string and password a string
will return
```json
{"jwt":{...}}
```
- where {...} is a JWT (string)
2020-01-07 19:58:46 +00:00
##### Step 3 - insert an event
2020-01-06 10:44:37 +00:00
```html
/events
```
- public endpoint
2020-01-04 09:03:18 +00:00
- connect your sse-client to this endpoint
2020-01-06 10:44:37 +00:00
```html
/insert
```
- authenticated endpoint
2020-01-04 09:03:18 +00:00
- POST JSON to insert an event
```json
2020-01-07 19:58:46 +00:00
{"event":{...}, "collection_id":{...}, "timestamp":{...}, "data":{...}}
2020-01-04 09:03:18 +00:00
```
2020-01-07 19:58:46 +00:00
- where {...} is for the event a string, collection_id is an assigned uuid v4 for the event collection, timestamp is the epoch unix timestamp when you want the event to become the current event, and data is any JSON you want
2020-01-04 09:03:18 +00:00
2020-01-06 10:44:37 +00:00
will return
```json
2020-01-07 00:22:22 +00:00
{"id":{...}}
2020-01-06 10:44:37 +00:00
```
2020-01-07 00:22:22 +00:00
- where {...} is the uuid (string) of the event
2020-01-06 10:44:37 +00:00
2020-01-07 19:58:46 +00:00
##### Optional Endpoints
2020-01-06 10:44:37 +00:00
```html
2020-01-07 19:58:46 +00:00
/events/collections/{collection_id}
2020-01-06 10:44:37 +00:00
```
- authenticated endpoint
2020-01-07 19:58:46 +00:00
- do a GET request where {collection_id} is the uuid of the collection you want (sorted by ascending timestamp)
2020-01-04 23:17:49 +00:00
2020-01-06 10:44:37 +00:00
```html
2020-01-07 00:22:22 +00:00
/events/{id}/cancel
2020-01-06 10:44:37 +00:00
```
- authenticated endpoint
2020-01-07 00:22:22 +00:00
- do a GET request where id is the uuid of the event to cancel a future event
2020-01-04 09:03:18 +00:00
2020-01-01 02:43:18 +00:00
### Features
2020-01-04 09:03:18 +00:00
* Very performant with a low memory footprint
2020-01-01 06:26:21 +00:00
* Real-time Event Stream via SSE
2020-01-01 06:24:50 +00:00
* CORS support
2020-01-01 07:59:38 +00:00
* Handles SSE client timeouts
2020-01-06 07:24:24 +00:00
* Provides user authentication with JWTs and Bcrypt(ed) passwords
2020-01-04 23:24:30 +00:00
* Handles future events via Epoch UNIX timestamp
2020-01-01 02:43:18 +00:00
* Stateful immutable event persistence
2020-01-04 23:24:30 +00:00
* Insert event via JSON POST request
2020-01-01 07:59:38 +00:00
* Sync latest events on SSE client connection
2020-01-04 09:03:18 +00:00
* Event log via GET request
2020-01-04 23:24:30 +00:00
* Event cancellation via GET request
2020-01-01 02:43:18 +00:00
2020-01-01 02:28:56 +00:00
### Use
2019-12-16 18:04:14 +00:00
2019-12-31 20:29:09 +00:00
```rust
2020-01-01 05:09:38 +00:00
use broker::{broker_run};
2019-12-31 20:29:09 +00:00
#[actix_rt::main]
async fn main() -> std::result::Result<(), std::io::Error> {
2020-01-06 03:12:55 +00:00
broker_run("http://localhost:3000".to_owned()).await
2019-12-31 20:29:09 +00:00
}
```
2020-01-06 03:12:55 +00:00
- the only param is the origin you want to allow - wildcard is not supported
2020-01-06 03:59:54 +00:00
- the PORT needs to be passed in as an environment variable
- the ORIGIN needs to be passed in as an environment variable
- the EXPIRY (for jwts) needs to be passed in as an environment variable
2020-01-06 06:55:34 +00:00
- the SECRET (for jwts) needs to be passed in as an environment variable
2020-01-01 19:23:08 +00:00
- the file database saves to ``` ./tmp ``` of the project root
2019-12-31 20:29:09 +00:00
2020-01-01 08:15:35 +00:00
### Run Example
2019-12-31 20:29:09 +00:00
2020-01-01 02:28:56 +00:00
- ``` make ```
2020-01-01 03:55:10 +00:00
2020-01-02 14:31:57 +00:00
### Under the Hood
2020-01-04 09:03:18 +00:00
- [actix-web](https://crates.io/crates/actix-web) - web framework
2020-01-02 14:31:57 +00:00
- [sled](https://crates.io/crates/sled) - embedded database
- [sse-actix-web](https://crates.io/crates/sse-actix-web) - sse server
2020-01-01 03:55:10 +00:00
### Inspiration
* [React Hooks](https://reactjs.org/docs/hooks-intro.html)
* [Meteor](https://meteor.com)
* [MongoDB](https://www.mongodb.com/)
* [Pusher](https://pusher.com)
* [Event Sourcing](https://microservices.io/patterns/data/event-sourcing.html)
* [Best in Place](https://github.com/bernat/best_in_place)
* [Brock Whitten](https://www.youtube.com/watch?v=qljYMEfVukU)