Awesome
Cycle Node Http Server
Driver and router component for manage HTTP/HTTPS services with Cycle.js
Installation with NPM
npm i cycle-node-http-serve --save
HTTP/HTTPS Driver
makeHttpServerDriver(config)
Create the driver
Arguments
config
with specifics optionsmiddlewares : Array
: array of express compatible middlewares like serveStatic or bodyParserrender: (template) => template
: a template engine renderer, call withreq.response.render(template)
Basic usage
const {run} = require('@cycle/run');
const {makeHttpServerDriver} = require('cycle-node-http-server');
function main(sources){
const {httpServer} = sources;
const sinks = {
}
return sinks;
}
const drivers = {
httpServer: makeHttpServerDriver()
}
run(main,drivers)
Create a HTTP Server Instance
To create a server instance, we need to send a config stream to the httpServer output. Like this :
const httpCreate$ = xs.of({
id: 'http',
action: 'create',
port: 1983
});
const sinks = {
httpServer: httpCreate$
}
create action config:
id
: the instance reference name. Needed to select the server stream on input.action:'create'
: the action nameport
: see server.listen([port][, hostname][, backlog][, callback]) on NodeJS Apihostname
: see server.listen([port][, hostname][, backlog][, callback]) on NodeJS Apibacklog
: see server.listen([port][, hostname][, backlog][, callback]) on NodeJS Apihandle
: see server.listen(handle[, callback]) on NodeJS Apipath
: see server.listen(path[, callback]) on NodeJS Apisecured
: set at true to create a HTTPS server.securedOptions
: Needed ifsecured
istrue
see Node HTTPS createServer optionsmiddlewares : Array
: array of express compatible middlewares like serveStatic or bodyParser
Basic example with HTTPS
const securedOptions = {
key: fs.readFileSync(`${__dirname}/certs/key.pem`),
cert: fs.readFileSync(`${__dirname}/certs/cert.pem`)
};
const httpsCreate$ = xs.of({
id: 'https',
action: 'create',
port: 1984,
secured: true,
securedOptions
});
Close server instance
To close a server instance we need to send a config stream to the httpServer output.
const httpClose$ = xs.of({
id: 'http',
action: 'close'
});
const sinks = {
httpServer: httpClose$
}
create action config:
id
: the instance reference name. Needed to select the server stream on input.action:'close'
: the action name
Select a server stream with select(id)
Select the server width this specific id
Return Object
const http = httpServer.select('http');
Get events with event(name)
Get event with name
stream from a http
object.
const http = httpServer.select('http');
const httpReady$ = http.events('ready');
const httpRequest$ = http.events('request');
Return Stream
Event ready
Dispatched when the server is ready to listen.
Returned values :
event
:'ready'
instanceId
: The instance idinstance
: the original Node.js server object
Event request
Dispatched when the server received a request.
See Request
object above.
Request
object
Properties
event
:'request'
,instanceId
: The instance idoriginal
: original NodeJS request object,url
: request's url,method
: request's method (POST,GET,PUT, etc...),headers
: request's headers,body
: the body request.undefined
by default. See BodyParser middlewareresponse
: the response object
Response
object
Methods
send()
Format response for driver output.
Arguments
content
: the body responseoptions
:statusCode
: default200
headers
: defaultnull
statusMessage
: defaultnull
Return formatted object for driver output
json()
Format response in json.
See send()
text()
Format response in plain text.
See send()
html()
Format response in html.
See send()
render()
Format response with the render engine defined in makeHttpServerDriver()
options.
redirect()
Format response redirection for driver output.
Arguments
path
: path to redirectoptions
:statusCode
: default302
headers
: defaultnull
statusMessage
: defaultnull
Return formatted object for driver output
Basic Usage
const {run} = require('@cycle/run');
const {makeHttpServerDriver} = require('cycle-node-http-server');
function main(sources){
const {httpServer} = sources;
// get http source
const http = httpServer.select('http');
// get requests
const serverRequest$ = http.events('request');
const httpCreate$ = xs.of({
id: 'http',
action: 'create',
port: 1983
});
// response formated with a helper response object
// Response in text format : 'covfefe'
const response$ = serverRequest$.map( req => req.response.text('covfefe') );
const sinks = {
httpServer: xs.merge(httpCreate$,response$)
}
return sinks;
}
const drivers = {
httpServer: makeHttpServerDriver()
}
run(main,drivers)
Routing
A Router component using switch-path
Arguments
Router(sources,routes)
sources
: Cycle.js sources object with a specific sourcerequest$
, a stream of http(s) requests.routes
: a collection of routes. See switch-path
Return stream
Example
const {makeHttpServerDriver, Router} = require('cycle-node-http-server');
function main(sources) {
const { httpServer } = sources;
// get http source
const http = httpServer.select('http');
// create the http server
const httpCreate$ = xs.of({
id: 'http',
action: 'create',
port: 1983,
});
// get requests
const serverRequest$ = http.events('request');
// routing
const router$ = Router({ request$: serverRequest$ }, {
'/': sources => Page(Object.assign({}, sources, { props$: xs.of({ desc: 'home' }) })),
'/user/:id': id => sources => Page(Object.assign({}, sources, { props$: xs.of({ desc: `user/${id}` }) })),
});
const sinks = {
httpServer: xs.merge(httpCreate$, router$.map(c => c.httpServer).flatten()),
};
return sinks;
}
function Page(sources) {
const { props$, request$ } = sources;
const sinks = {
httpServer: xs.combine(props$, request$).map(([props, req]) => req.response.text(props.desc))
}
return sinks;
}
Cooking with middlewares
Here are discribed two usefull express middlewares.
serveStatic
It is used to serve static files ( images, css, etc... )
Basic usage
const serveStatic = require('serve-static');
const {makeHttpServerDriver} = require('cycle-node-http-server');
const drivers = {
httpServer: makeHttpServerDriver({middlewares:[serveStatic('./public')]})
}
bodyParser
It is used to parse request body and return a full formated body.
Basic usage
const bodyParser = require('body-parser');
const {makeHttpServerDriver} = require('cycle-node-http-server');
const drivers = {
httpServer: makeHttpServerDriver({
middlewares: [
// two parsers used to format body POST request in json
bodyParser.urlencoded({ extended: true }),
bodyParser.json()
]
})
}
Using Snabbdom
Snabbdom is the Virtual DOM using by @cycle/dom. It's possible to use it in server side with snabbdom-to-html.
A small helper to use snabbdom
with cycle-node-http-server
const snabbdomInit = require('snabbdom-to-html/init');
const snabbdomModules = require('snabbdom-to-html/modules');
const {makeHttpServerDriver} = require('cycle-node-http-server');
export default function vdom(modules=[
snabbdomModules.class,
snabbdomModules.props,
snabbdomModules.attributes,
snabbdomModules.style
]){
return snabbdomInit(modules);
}
const drivers = {
httpServer: makeHttpServerDriver({
render: vdom()
})
}
In main
function, snabbdom used with JSX
const response$ = request$.map( req => req.response.render(
<div>
Pouet
</div>
))
License
MIT