Skip to content

Instantly share code, notes, and snippets.

@iansinnott
Last active June 12, 2017 05:40
Show Gist options
  • Save iansinnott/20c8c8b0dcdcefc26920a75438e9b09d to your computer and use it in GitHub Desktop.
Save iansinnott/20c8c8b0dcdcefc26920a75438e9b09d to your computer and use it in GitHub Desktop.
Amazing Epic Server
const http = require('http');
const { createApp, send } = require('epic-server');
/**
* Create your epics.
* type Epic = (req$: Observable<Request>, ...dependencies: any) => Observable<Response>
* type of Request and Response TBD. Will related to nodes (req, res) objects
* passed to the handler in createServer.
*/
const create = (rec$, { db /* Any helpers could go here */ }) =>
rec$.post('/users/new')
.mergeMap(req =>
db.users.insert(req.body)
.map(user => send(user))
.catch(err => send(err, { status: 500 })))
const read = (rec$, { db }) =>
rec$.get('/users')
.mergeMap(req =>
db.users.findAll()
.map(users => send(users))
.catch(err => send(err, { status: 500 })))
// const update = (req$) => ...
// const del = (req$) => ...
const userCrudEpic = combineEpics(create, read /*, update, del */);
const epic = combineEpics(
userCrudEpic,
// Other epics...
);
// Import any dependencies
const db = require('./db');
// Create the app (Magic!). Depdencies are injected into epics
const app = createApp(epic, { db });
// Everything else is as you would expect
const server = http.createServer(app);
server.listen(3000, () => console.log('Listening at localhost:3000'));
@iansinnott
Copy link
Author

iansinnott commented Jun 5, 2017

I haven't thought much about middleware yet, but I imagine it would either be simple map/mergeMap calls or a different sort of epic where the signature is request stream to request stream: (req$: Observable<Request>) => Observable<Request>

@BerkeleyTrue
Copy link

What's your reasoning behind req/res first instead of route first?

@iansinnott
Copy link
Author

I was thinking it would make writing middleware pretty straight forward since middleare doesn't necessarily care about route. It also just made more sense to me to think of the incoming requests as a stream

@BerkeleyTrue
Copy link

Both of your examples still are route first, though. Yes, while middleware doesn't care about routes, most servers are mainly routes, not middleware. Route agnostic middleware are usually very few on a back end.

@iansinnott
Copy link
Author

I guess I don't know what you mean by route first then. Your right, my examples are pretty much all routes and this is probably the case for most peoples servers. But to me this API (get,post,etc) feels pretty simple to work with and similar to express. The helper methods on top of the observable are just a filter function just like ofType in redux-observable. I.e. req$.filter(req => req.url === '/some/path' && req.method === 'GET').

I supposed the short answer is that I like the way epics work in redux-observable on the front end, and was hoping to bring a similar API to the stream of all requests hitting the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment