Comparing version 1.0.12 to 1.0.13
import { Body } from "./Body"; | ||
import { Uri } from "./Uri"; | ||
import { Response } from "./Response"; | ||
export interface HttpMessage { | ||
@@ -16,3 +17,1 @@ headers: object; | ||
export declare type HttpHandler = (Request) => Response; | ||
export interface Response extends HttpMessage { | ||
} |
@@ -18,7 +18,5 @@ import { Response } from "./Response"; | ||
private filters; | ||
private preFilters; | ||
constructor(path: string, method: string, handler: HttpHandler); | ||
withRoutes(routes: ResourceRoutingHttpHandler): ResourceRoutingHttpHandler; | ||
withFilter(filter: (HttpHandler) => HttpHandler): ResourceRoutingHttpHandler; | ||
withPreFilter(filter: (Request) => Request): ResourceRoutingHttpHandler; | ||
withHandler(path: string, method: string, handler: HttpHandler): ResourceRoutingHttpHandler; | ||
@@ -25,0 +23,0 @@ asServer(port: number): Http4jsServer; |
@@ -24,3 +24,2 @@ "use strict"; | ||
this.filters = []; | ||
this.preFilters = []; | ||
this.defaultNotFoundHandler = function (request) { | ||
@@ -42,6 +41,2 @@ var notFoundBody = request.method + " to " + request.uri.template + " did not match routes"; | ||
}; | ||
ResourceRoutingHttpHandler.prototype.withPreFilter = function (filter) { | ||
this.preFilters.push(filter); | ||
return this; | ||
}; | ||
ResourceRoutingHttpHandler.prototype.withHandler = function (path, method, handler) { | ||
@@ -81,14 +76,13 @@ var existingPath = this.root != "/" ? this.root : ""; | ||
var matchedHandler = exactMatch || fuzzyMatch; | ||
var preFilteredRequest = this.preFilters.reduce(function (acc, next) { return next(acc); }, request); | ||
if (matchedHandler) { | ||
var handler = matchedHandler.handler; | ||
var filtered = this.filters.reduce(function (acc, next) { return next(acc); }, handler); | ||
preFilteredRequest.pathParams = matchedHandler.path.includes("{") | ||
? Uri_1.Uri.of(matchedHandler.path).extract(preFilteredRequest.uri.path).matches | ||
request.pathParams = matchedHandler.path.includes("{") | ||
? Uri_1.Uri.of(matchedHandler.path).extract(request.uri.path).matches | ||
: {}; | ||
return filtered(preFilteredRequest); | ||
return filtered(request); | ||
} | ||
else { | ||
var filtered = this.filters.reduce(function (acc, next) { return next(acc); }, this.defaultNotFoundHandler); | ||
return filtered(preFilteredRequest); | ||
return filtered(request); | ||
} | ||
@@ -95,0 +89,0 @@ }; |
@@ -154,5 +154,5 @@ "use strict"; | ||
return new Response_1.Response(200, new Body_1.Body(req.getHeader("pre-filter") || "hello, world!")); | ||
}).withPreFilter(function (req) { | ||
return req.setHeader("pre-filter", "hello from pre-filter"); | ||
}) | ||
}).withFilter(function (handler) { return function (req) { | ||
return handler(req.setHeader("pre-filter", "hello from pre-filter")); | ||
}; }) | ||
.match(new Request_1.Request("GET", "/")); | ||
@@ -159,0 +159,0 @@ assert_1.equal(response.bodyString(), "hello from pre-filter"); |
38
index.js
@@ -6,40 +6,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Request_1 = require("./src/main/core/Request"); | ||
var RoutingHttpHandler_1 = require("./src/main/core/RoutingHttpHandler"); | ||
var Response_1 = require("./src/main/core/Response"); | ||
var Client_1 = require("./src/main/core/Client"); | ||
var Body_1 = require("./src/main/core/Body"); | ||
var Uri_1 = require("./src/main/core/Uri"); | ||
var handler = function (req) { | ||
var bodyString = "<h1>" + req.method + " to " + req.uri.href + " with headers " + Object.keys(req.headers) + "</h1>"; | ||
return new Response_1.Response(200, new Body_1.Body(Buffer.from(bodyString))); | ||
}; | ||
var headerFilter = function (handler) { | ||
return function (req) { | ||
return handler(req.setHeader("filter", "1")); | ||
}; | ||
}; | ||
var moreRoutes = RoutingHttpHandler_1.routes("/bob/{id}", "POST", function (req) { | ||
return new Response_1.Response(201, new Body_1.Body("created a " + req.path)); | ||
}); | ||
RoutingHttpHandler_1.routes("/path", "GET", handler) | ||
.withHandler("/tom", "GET", handler) | ||
.withRoutes(moreRoutes) | ||
.withFilter(headerFilter) | ||
.asServer(3000).start(); | ||
var getRequest = new Request_1.Request("GET", Uri_1.Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
var postRequest = new Request_1.Request("GET", Uri_1.Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
var client = Client_1.HttpClient; | ||
client(getRequest).then(function (succ) { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
client(postRequest).then(function (succ) { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
__export(require("./src/main/core/RoutingHttpHandler")); | ||
@@ -46,0 +8,0 @@ __export(require("./src/main/core/Request")); |
48
index.ts
@@ -1,49 +0,1 @@ | ||
import {Request} from "./src/main/core/Request"; | ||
import {HttpHandler} from "./src/main/core/HttpMessage"; | ||
import {routes} from "./src/main/core/RoutingHttpHandler"; | ||
import {Response} from "./src/main/core/Response"; | ||
import {HttpClient} from "./src/main/core/Client"; | ||
import {Body} from "./src/main/core/Body"; | ||
import {Uri} from "./src/main/core/Uri"; | ||
let handler = (req: Request) => { | ||
let bodyString = `<h1>${req.method} to ${req.uri.href} with headers ${Object.keys(req.headers)}</h1>`; | ||
return new Response(200, new Body(Buffer.from(bodyString))) | ||
}; | ||
let headerFilter = (handler: HttpHandler) => { | ||
return (req: Request) => { | ||
return handler(req.setHeader("filter", "1")); | ||
} | ||
}; | ||
let moreRoutes = routes("/bob/{id}", "POST", (req) => { | ||
return new Response(201, new Body("created a " + req.path)) | ||
}); | ||
routes("/path", "GET", handler) | ||
.withHandler("/tom", "GET", handler) | ||
.withRoutes(moreRoutes) | ||
.withFilter(headerFilter) | ||
.asServer(3000).start(); | ||
let getRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
let postRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
let client = HttpClient; | ||
client(getRequest).then(succ => { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
client(postRequest).then(succ => { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
export * from "./src/main/core/RoutingHttpHandler"; | ||
@@ -50,0 +2,0 @@ export * from "./src/main/core/Request"; |
{ | ||
"name": "http4js", | ||
"version": "1.0.12", | ||
"version": "1.0.13", | ||
"description": "A lightweight HTTP toolkit", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -5,2 +5,14 @@ ## Http4js | ||
If you wrote a thin API layer that translated the wire representation of HTTP into a few domain objects: Request, Response and Routing, and translated back again, you essentially wind up with the whole of http4js. | ||
This seemingly basic idea is the beauty and power of http4js and the SaaF (Server as a Function) concept. | ||
We translate a wire request into a Request object. Our server is a function from Request -> Response, we translate a Response to a wire response. | ||
We write all our routing logic with our Routing domain object. | ||
Hence we can run server in memory and test our entire stack and therefore the only added benefit of functional testing is to test the translation between wire and domain. | ||
We inject all of our dependencies to our Server so testing using fakes is easy peasy. We can even write simple fakes of external dependencies and spin them up in memory. | ||
#### To run: | ||
@@ -32,1 +44,55 @@ | ||
- write docs | ||
- provide examples in this README | ||
#### Example | ||
``` | ||
import {Request} from "./src/main/core/Request"; | ||
import {HttpHandler} from "./src/main/core/HttpMessage"; | ||
import {routes} from "./src/main/core/RoutingHttpHandler"; | ||
import {Response} from "./src/main/core/Response"; | ||
import {HttpClient} from "./src/main/core/Client"; | ||
import {Body} from "./src/main/core/Body"; | ||
import {Uri} from "./src/main/core/Uri"; | ||
& | ||
let handler = (req: Request) => { | ||
let bodyString = `<h1>${req.method} to ${req.uri.href} with headers ${Object.keys(req.headers)}</h1>`; | ||
return new Response(200, new Body(Buffer.from(bodyString))) | ||
}; | ||
& | ||
let headerFilter = (handler: HttpHandler) => { | ||
return (req: Request) => { | ||
return handler(req.setHeader("filter", "1")); | ||
} | ||
}; | ||
& | ||
let moreRoutes = routes("/bob/{id}", "POST", (req) => { | ||
return new Response(201, new Body("created a " + req.path)) | ||
}); | ||
& | ||
routes("/path", "GET", handler) | ||
.withHandler("/tom", "GET", handler) | ||
.withRoutes(moreRoutes) | ||
.withFilter(headerFilter) | ||
.asServer(3000).start(); | ||
& | ||
let getRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
& | ||
let postRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules"); | ||
& | ||
let client = HttpClient; | ||
& | ||
client(getRequest).then(succ => { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
& | ||
client(postRequest).then(succ => { | ||
console.log("body string"); | ||
console.log(succ.body.bodyString()); | ||
console.log("headers"); | ||
console.log(succ.headers); | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
97
157114
1000