fastify
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -18,11 +18,11 @@ 'use strict' | ||
fastify.get('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
fastify | ||
.get('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
.post('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
fastify.post('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
server.listen(8000, function (err) { | ||
server.listen(3000, function (err) { | ||
if (err) { | ||
@@ -29,0 +29,0 @@ throw err |
'use strict' | ||
const wayfarer = require('wayfarer') | ||
const fastJsonStringify = require('fast-json-stringify') | ||
const urlUtil = require('url') | ||
const stripUrl = require('pathname-match') | ||
const jsonParser = require('body/json') | ||
const schema = Symbol('schema') | ||
const supportedMethods = ['GET', 'POST'] | ||
const supportedMethods = ['GET', 'POST', 'PUT'] | ||
const validation = require('./lib/validation') | ||
const buildSchema = validation.buildSchema | ||
const validateSchema = validation.validateSchema | ||
const serialize = validation.serialize | ||
function build () { | ||
const router = wayfarer() | ||
const router = wayfarer('/404') | ||
const map = new Map() | ||
router.on('/404', defaultRoute) | ||
@@ -16,2 +22,3 @@ // shorthand methods | ||
fastify.post = post | ||
fastify.put = put | ||
// extended route | ||
@@ -23,23 +30,25 @@ fastify.route = route | ||
function fastify (req, res) { | ||
router(req.url, req, res) | ||
router(stripUrl(req.url), req, res) | ||
} | ||
function get (url, schema, handler) { | ||
return route({ | ||
method: 'GET', | ||
url: url, | ||
schema: schema, | ||
handler: handler | ||
}) | ||
return _route('GET', url, schema, handler) | ||
} | ||
function post (url, schema, handler) { | ||
return route({ | ||
method: 'POST', | ||
url: url, | ||
schema: schema, | ||
handler: handler | ||
}) | ||
return _route('POST', url, schema, handler) | ||
} | ||
function put (url, schema, handler) { | ||
return _route('PUT', url, schema, handler) | ||
} | ||
function _route (method, url, schema, handler) { | ||
if (!handler && typeof schema === 'function') { | ||
handler = schema | ||
schema = {} | ||
} | ||
return route({ method, url, schema, handler }) | ||
} | ||
function route (opts) { | ||
@@ -50,4 +59,8 @@ if (supportedMethods.indexOf(opts.method) === -1) { | ||
opts[schema] = fastJsonStringify(opts.schema.out) | ||
if (!opts.handler) { | ||
throw new Error(`Missing handler function for ${opts.method}:${opts.url} route.`) | ||
} | ||
buildSchema(opts) | ||
if (map.has(opts.url)) { | ||
@@ -64,2 +77,3 @@ if (map.get(opts.url)[opts.method]) { | ||
} | ||
return fastify | ||
} | ||
@@ -69,4 +83,8 @@ | ||
function parsed (err, body) { | ||
if (err) throw err | ||
handleNode(handle, params, req, res, body) | ||
if (err) { | ||
res.statusCode = 422 | ||
res.end() | ||
return | ||
} | ||
handleNode(handle, params, req, res, body, null) | ||
} | ||
@@ -82,6 +100,11 @@ return parsed | ||
if (req.method === 'GET') { | ||
handleNode(handle, params, req, res, null) | ||
} else if (req.method === 'POST') { | ||
jsonParser(req, bodyParsed(handle, params, req, res)) | ||
if (handle && req.method === 'GET') { | ||
handleNode(handle, params, req, res, null, urlUtil.parse(req.url, true).query) | ||
} else if (handle && (req.method === 'POST' || req.method === 'PUT')) { | ||
if (req.headers['content-type'] === 'application/json') { | ||
jsonParser(req, bodyParsed(handle, params, req, res)) | ||
} else { | ||
res.statusCode = 415 | ||
res.end() | ||
} | ||
} else { | ||
@@ -96,3 +119,3 @@ res.statusCode = 404 | ||
function handleNode (handle, params, req, res, body) { | ||
function handleNode (handle, params, req, res, body, query) { | ||
if (!handle) { | ||
@@ -103,5 +126,13 @@ res.statusCode = 404 | ||
const request = new Request(params, req, body) | ||
const valid = validateSchema(handle, params, body, query) | ||
if (valid !== true) { | ||
res.statusCode = 400 | ||
res.end(valid) | ||
return | ||
} | ||
handle.handler(request, function reply (err, statusCode, data) { | ||
const request = new Request(params, req, body, query) | ||
handle.handler(request, reply) | ||
function reply (err, statusCode, data) { | ||
if (err) { | ||
@@ -118,10 +149,16 @@ res.statusCode = 500 | ||
res.statusCode = statusCode | ||
res.end(handle[schema](data)) | ||
}) | ||
res.end(serialize(handle, data)) | ||
} | ||
} | ||
function Request (params, req, body) { | ||
function defaultRoute (params, req, res) { | ||
res.statusCode = 404 | ||
res.end() | ||
} | ||
function Request (params, req, body, query) { | ||
this.params = params | ||
this.req = req | ||
this.body = body | ||
this.query = query | ||
} | ||
@@ -128,0 +165,0 @@ } |
{ | ||
"name": "fastify", | ||
"version": "0.0.1", | ||
"description": "go away", | ||
"version": "0.1.0", | ||
"description": "Fast and low overhead web framework, for Node.js", | ||
"main": "fastify.js", | ||
"scripts": { | ||
"test": "standard | snazzy && tap test/*.js" | ||
"test": "standard | snazzy && tap test/*.test.js" | ||
}, | ||
@@ -30,14 +30,19 @@ "repository": { | ||
"hapi": "^15.1.1", | ||
"koa": "^1.2.4", | ||
"pre-commit": "^1.1.3", | ||
"request": "^2.75.0", | ||
"restify": "^4.1.1", | ||
"snazzy": "^5.0.0", | ||
"standard": "^8.2.0", | ||
"standard": "^8.4.0", | ||
"take-five": "^1.3.0", | ||
"tap": "^7.1.2" | ||
}, | ||
"dependencies": { | ||
"ajv": "^4.7.7", | ||
"body": "^5.1.0", | ||
"fast-json-stringify": "^0.8.1", | ||
"is-my-json-valid": "^2.14.0", | ||
"fast-json-stringify": "^0.10.0", | ||
"fast-safe-stringify": "^1.1.0", | ||
"pathname-match": "^1.2.0", | ||
"wayfarer": "^6.2.1" | ||
} | ||
} |
196
README.md
@@ -1,2 +0,194 @@ | ||
# beo | ||
go away | ||
# Fastify [![Build Status](https://travis-ci.org/mcollina/fastify.svg)](https://travis-ci.org/mcollina/fastify) [![Coverage Status](https://coveralls.io/repos/github/mcollina/fastify/badge.svg?branch=master)](https://coveralls.io/github/mcollina/fastify?branch=master) | ||
[Extremely fast](#benchmarks) node.js web framework, inspired by | ||
[Express][express], [Hapi][hapi] and [Restify][restify]. | ||
Fastify is alpha software in *active development*, feel free to | ||
contribute! | ||
* [Installation](#install) | ||
* [Usage](#usage) | ||
* [Benchmarks](#benchmarks) | ||
* [API](#api) | ||
* [Team](#team) | ||
* [Acknowledgements](#acknowledgements) | ||
* [License](#license) | ||
## Install | ||
``` | ||
npm install fastify --save | ||
``` | ||
## Usage | ||
```js | ||
'use strict' | ||
const fastify = require('fastify')() | ||
const http = require('http') | ||
const server = http.createServer(fastify) | ||
const schema = { | ||
out: { | ||
type: 'object', | ||
properties: { | ||
hello: { | ||
type: 'string' | ||
} | ||
} | ||
} | ||
} | ||
fastify | ||
.get('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
.get('/no-schema', function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
.post('/', schema, function (req, reply) { | ||
reply(null, { hello: 'world' }) | ||
}) | ||
server.listen(8000, function (err) { | ||
if (err) { | ||
throw err | ||
} | ||
console.log(`server listening on ${server.address().port}`) | ||
}) | ||
``` | ||
<a name="benchmarks"></a> | ||
## Benchmarks | ||
As far as we know, it is one of the fastest web frameworks in town: | ||
* Hapi: 2200 req/sec | ||
* Restify: 6133 req/sec | ||
* Express: 8534 req/sec | ||
* Koa: 9640 req/sec | ||
* *Fastify: 17140 req/sec* | ||
All benchmarks where average taken over 5 seconds, on the second run of `autocannon -c 100 -d 5 -p 10 localhost:3000`. | ||
<a name="api"></a> | ||
## API | ||
* <a href="#constructor"><code><b>fastify()</b></code></a> | ||
* <a href="#route"><code>fastify.<b>route()</b></code></a> | ||
* <a href="#get"><code>fastify.<b>get()</b></code></a> | ||
* <a href="#post"><code>fastify.<b>post()</b></code></a> | ||
* <a href="#put"><code>fastify.<b>put()</b></code></a> | ||
* <a href="#request"><code>fastify.<b>Request</b></code></a> | ||
<a name="constructor"></a> | ||
### fastify(req, res) | ||
Returns a new fastify instance, which is a function with some method | ||
attached. `req` and `res` are the request and response objects from Node | ||
Core. | ||
```js | ||
const fastify = require('fastify')() | ||
const http = require('http') | ||
const server = http.createServer(fastify) | ||
server.listen(8000, function (err) { | ||
if (err) { | ||
throw err | ||
} | ||
console.log(`server listening on ${server.address().port}`) | ||
}) | ||
``` | ||
<a name="route"></a> | ||
### fastify.route(options) | ||
Options: | ||
* `method`: currently it supports only GET, POST and PUT. | ||
* `url`: the path of the url to match this route, it uses | ||
[wayfarer][wayfarer] as a router. | ||
* `schema`: an object containing the schemas for the request and response. They need to be in | ||
[JSON Schema][jsonschema] format: | ||
* `payload`: validates the body of the request if it is a POST or a | ||
PUT. It uses [ajv][ajv]. | ||
* `querystring`: validates the querystring. It uses [ajv][ajv]. | ||
* `params`: validates the params. It uses [ajv][ajv]. | ||
* `out`: filter and generate a schema for the response, setting a | ||
schema allows us to have 10-20% more throughput. It uses | ||
[fast-json-stringify][fast-json-stringify]. | ||
* `handler(request, repy(err, statusCode, object)`: the function that will handle this request. | ||
The `request` parameter is defined in [Request](#request). | ||
`object` inside the request is a JavaScript object that will be | ||
JSONified, possibly using the schema defined `options.schema.out`. | ||
For POST and PUT, the incoming request body will be parsed. | ||
<a name="get"></a> | ||
### fastify.get(path, [schema], handler) | ||
Calls [route](#route) with the given path, schemas and handler, setting | ||
up the GET method. | ||
<a name="post"></a> | ||
### fastify.post(path, [schema], handler) | ||
Calls [route](#route) with the given path, schemas and handler, setting | ||
up the POST method. | ||
<a name="put"></a> | ||
### fastify.put(path, [schema], handler) | ||
Calls [route](#route) with the given path, schemas and handler, setting | ||
up the PUT method. | ||
<a name="request"></a> | ||
### Request | ||
An object including the following properties: | ||
* `query` - the parsed querystring | ||
* `body` - the body | ||
* `params` - the params matching the URL | ||
* `req` - the incoming HTTP request from Node core | ||
<a name="team"></a> | ||
## The Team | ||
### Matteo Collina | ||
<https://github.com/mcollina> | ||
<https://www.npmjs.com/~matteo.collina> | ||
<https://twitter.com/matteocollina> | ||
### Tomas Della Vedova | ||
<https://github.com/delvedor> | ||
<https://www.npmjs.com/~delvedor> | ||
<https://twitter.com/delvedor> | ||
<a name="acknowledgements"></a> | ||
## Acknowledgements | ||
This project was kindly sponsored by [nearForm](http://nearform.com). | ||
## License | ||
Licensed under [MIT](./LICENSE). | ||
[express]: http://expressjs.com | ||
[hapi]: http://hapijs.com/ | ||
[restify]: http://restify.com/ | ||
[wayfarer]: http://npm.im/wayfarer | ||
[fast-json-stringify]: http://npm.im/fast-json-stringify | ||
[ajv]: http://npm.im/ajv |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
28485
23
833
195
6
10
7
+ Addedajv@^4.7.7
+ Addedfast-safe-stringify@^1.1.0
+ Addedpathname-match@^1.2.0
+ Addedajv@4.11.8(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedco@4.6.0(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfast-json-stringify@0.10.5(transitive)
+ Addedfast-safe-stringify@1.2.3(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedisarray@2.0.5(transitive)
+ Addedjson-stable-stringify@1.1.1(transitive)
+ Addedjsonify@0.0.1(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedpathname-match@1.2.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
- Removedis-my-json-valid@^2.14.0
- Removedfast-json-stringify@0.8.1(transitive)
- Removedgenerate-function@2.3.1(transitive)
- Removedgenerate-object-property@1.2.0(transitive)
- Removedis-my-ip-valid@1.0.1(transitive)
- Removedis-my-json-valid@2.20.6(transitive)
- Removedis-property@1.0.2(transitive)
- Removedjsonpointer@5.0.1(transitive)
Updatedfast-json-stringify@^0.10.0