Effects-as-data server
effects-as-data-server
is a lightweight server built on Koa. It is designed for building web applications with effects-as-data.
The guiding principals behind the development of this server are:
- Routes should be functions that take JSON and return JSON, not functions that accept a
ctx
object and "return" by settings properties on that object. - Routes should be easy to unit test thoroughly.
- Rapid development with
effects-as-data
. This means rapid development and clean code. In my experience, web servers have a way of turning into spaghetti quickly. - Convention over configuration. Most of the time the default settings for this server will work for you and you can just focus on getting things done.
Table of Contents
Installation
npm i effects-as-data-server
Built-in Middleware
The following middleware is enabled by default. All, except koa-router
, can be disabled. See init below.
- koa-helmet
- koa-cookie
- koa-bodyparser
- koa-router
Usage
effects-as-data-server
comes bundled with effects-as-data-universal
by default.
Simple Example
const { init, cmds, send, router } = require("effects-as-data-server");
function* helloWorld({ body, query, params, headers, cookies }) {
const result = yield cmds.echo("hello world");
return send(result);
}
const { start, stop } = init({
port: 3000,
routes: [router.get("/hello-world", helloWorld)]
});
start().catch(console.error);
Unit test for Simple Example
const { helloWorld } = require("./path/to/hello-world");
const { args, testFn } = require("effects-as-data/test");
const { cmds } = require("effects-as-data-server");
test(
'helloWorld() should return "hello world"',
testFn(helloWorld, () => {
return args()
.yieldCmd(cmds.echo("hello world"))
.yieldReturns("hello world")
.returns(send("hello world"));
})
);
Using Custom EAD Interpreters
const { init } = require('effects-as-data-server');
function myCustomInterpreter () {
return 'I always return this';
}
const { start, stop } = init({
port: 3000,
interpreters: {
myCustomInterpreter
},
...
});
start().catch(console.error);
Simple Example with non EAD function
Just normal Koa.
const { init, router } = require("effects-as-data-server");
function helloWorld({ ctx, body, query, params, headers, cookies }) {
ctx.body = "hello world";
}
const { start, stop } = init({
port: 3000,
routes: [router.get("/hello-world", helloWorld)]
});
start().catch(console.error);
Using Koa middleware
The init function accepts an array of middleware functions.
const { init, router } = require('effects-as-data-server');
function customMiddleware (ctx, next) {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
}
const { start, stop } = init({
port: 3000,
middlware: [customMiddleware]
});
start().catch(console.error);
API
The following functions are exported from effects-as-data-server
.
init([options])
init
is used to initialize a server.
options
<[Object]> Effects-as-data server options. Can have the following fields:
routes
<[Array]> An array of routes created using the router
.context
<[Object]> Effects-as-data context.helmet
<[Object]> Options to be passed to koa-helmet
.disableHelmet
<[boolean]> Disable koa-helmet
if true
. Default is false
.middleware
<[Array]> An array of Koa middleware.port
<[Number]> The port on which the server runs.cookie
<[Object]> Options to be passed to koa-cookie
.disableCookie
<[Boolean]> Disable koa-cookie
if true
. Default is false
.bodyParser
<[Object]> Options to be passed to koa-bodyparser
.disableBodyParser
<[Boolean]> Disable koa-bodyparser
if true
. Default is false
.test
<[Boolean]> If true
, don't print startup messages to console. Default is false
.
Returns: An object with a start
and stop
function used to start and stop the server, respectively.
send([body], [status], [headers], [cookies])
Create a response to be returned by an EAD function and sent to the client.
body
<[Any]> The response body. requiredstatus
<[Number]> The response status. Ex: 200
, 204
, 400
, etc.headers
<[Object]> An object of headers. Ex: { 'X-Response-Time': 32 }
cookies
<[Array]> An array of cookies created using the createCookie
function.
Returns: An object containing the response body, status, headers, and cookies.
notFound([body], [headers], [cookies])
Create a not found response to be returned by an EAD function and sent to the client. This is a convenience function that wraps send
.
body
<[Any]> The response body. requiredheaders
<[Object]> An object of headers. Ex: { 'X-Response-Time': 32 }
cookies
<[Array]> An array of cookies created using the createCookie
function.
Returns: An object containing the response body, status of 404, headers, and cookies.
notAuthorized([body], [headers], [cookies])
Create a not authorized response to be returned by an EAD function and sent to the client. This is a convenience function that wraps send
.
body
<[Any]> The response body. requiredheaders
<[Object]> An object of headers. Ex: { 'X-Response-Time': 32 }
cookies
<[Array]> An array of cookies created using the createCookie
function.
Returns: An object containing the response body, status of 401, headers, and cookies.
createCookie([name], [value], [options])
Create a cookie which, internall, will be set with Koa's ctx.cookies.set
.
name
<[String]> Name of the cookie. requiredvalue
<[String]> Value of the cookie. requiredoptions
<[Object]> Options for Koa's ctx.cookies.set
function which is used to set the cookie.
Returns: A cookie to be set.
Router
The router is exported from effects-as-data-server
:
const { router } = require('effects-as-data-server');
const { start, stop } = init({
port: 3000,
routes: [
router.get('/api/users', function * () { ... })
router.get('/api/users/:id', function * () { ... })
router.post('/api/users', function * () { ... })
router.put('/api/users/:id', function * () { ... })
],
...
});
router.get([path], [function])
path
<[String]> A string path for this route. Ex: /api/users
function
<[Function]> An EAD function or a Koa middleware function.
Returns: A route for the routes
array passed to the init
function.
router.post([path], [function])
path
<[String]> A string path for this route. Ex: /api/users
function
<[Function]> An EAD function or a Koa middleware function.
Returns: A route for the routes
array passed to the init
function.
router.put([path], [function])
path
<[String]> A string path for this route. Ex: /api/users/32
function
<[Function]> An EAD function or a Koa middleware function.
Returns: A route for the routes
array passed to the init
function.
router.patch([path], [function])
path
<[String]> A string path for this route. Ex: /api/users/32
function
<[Function]> An EAD function or a Koa middleware function.
Returns: A route for the routes
array passed to the init
function.
router.delete([path], [function])
path
<[String]> A string path for this route. Ex: /api/users/32
function
<[Function]> An EAD function or a Koa middleware function.
Returns: A route for the routes
array passed to the init
function.