This repository was archived by the owner on May 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Middlewares
Marcel Kloubert edited this page Mar 14, 2023
·
1 revision
About [↑]
Middlewares are functions, which are optional and executed during the lifecycle of a request, before a handler is executed.
import cors from "cors"; // npm i cors && npm i -D @types/cors
import createServer, { json } from "@egomobile/http-server";
async function main() {
const app = createServer();
app.get("/", [cors(), json()], async (request, response) => {
response.write("Your input: " + JSON.stringify(request.body));
});
await app.listen();
}
main().catch(console.error);You can define them globally and/or for one or more single routes.
The common structure of a middleware is:
export type HttpMiddleware = (
request: IHttpRequest,
response: IHttpResponse,
next: NextFunction
) => any;To continue the request, you always have to execute next() function without arguments.
If you submit a non-falsy value, the request is handled as "failed":
const createMyMiddleware =
(/* you maybe want be able to parse options here */) => {
return async (request, response, next) => {
if (request.headers["foo"] === "bar")
// continue, because we have data we need
next();
else if (!request.headers["foo"])
// handle request as failed and execute
// the global error handler
next(new TypeError("We have no foo header here!"));
else {
// a more flexible way to
// cancel the request
response.writeHead(400);
response.write("foo header has wrong data!");
response.end(); // in that case, we have to end
// the request by ourselves
}
};
};
app.get("/", [createMyMiddleware()], async (request, response) => {
response.writeHead(204);
});Build-in middlewares [↑]
params() - Extract parameters from URL paths [↑]
import createServer, { params } from "@egomobile/http-server";
async function main() {
const app = createServer();
// this is not a classic middleware, more a path validator,
// which additionally extracts the path variables from the
// URL before the question mark and makes them available in 'params'
// property of 'request'
app.get(params("/foo/:bar"), async (request, response) => {
response.write("bar: " + request.params!.bar);
});
await app.listen();
}
main().catch(console.error);query() - Parse query / search parameters in URLs [↑]
import createServer, { query } from "@egomobile/http-server";
async function main() {
const app = createServer();
// get and parse query / search parameters
// and save them to 'query' property of 'request'
app.post("/", [query()], async (request, response) => {
response.write("Your query params: " + JSON.stringify(request.query));
});
await app.listen();
}
main().catch(console.error);json() - Parse to JSON object [↑]
import createServer, { json } from "@egomobile/http-server";
async function main() {
const app = createServer();
// handle the input as UTF-8 string and parse it as JSON,
// then save the object to 'body' property of 'request' and
// setup a limit of 64 MB (67108864)
// 👇
app.post("/", [json(64)], async (request, response) => {
response.write("Your input: " + JSON.stringify(request.body));
});
await app.listen();
}
main().catch(console.error);yaml() - Handle input data as YAML string [↑]
import createServer, { yaml } from "@egomobile/http-server";
async function main() {
const app = createServer();
// handle the input as UTF-8 YAML string and parse it to an object,
// then save the object to 'body' property of 'request' and
// setup a limit of 64 MB (67108864)
// 👇
app.post("/", [yaml(64)], async (request, response) => {
// input data is always wrapped
// input an array
const body: any[] = request.body;
response.write("Your input: " + JSON.stringify(body));
});
await app.listen();
}
main().catch(console.error);buffer() - Read whole input as buffer [↑]
import createServer, { buffer } from "@egomobile/http-server";
async function main() {
const app = createServer();
// read the whole body as buffer and write it to
// 'body' property of 'request' and setup a limit
// of 512 MB (536870912)
// 👇
app.post("/", [buffer(512)], async (request, response) => {
const body: Buffer = request.body;
response.write("Your input has a size of: " + String(body.length));
});
await app.listen();
}
main().catch(console.error);text() - Read whole input as string [↑]
import createServer, { text } from "@egomobile/http-server";
async function main() {
const app = createServer();
// read the whole body as UTF-8 string and write it to
// 'body' property of 'request' and setup a limit
// of 1 MB (1048576)
// 👇
app.post("/", [text(1)], async (request, response) => {
const body: string = request.body;
response.write("Your string input has a size of: " + body.length);
});
await app.listen();
}
main().catch(console.error);validate() - Validate input with the help of schemas [↑]
import createServer, { json, schema, validate } from "@egomobile/http-server";
interface IMySchema {
email: string;
name?: string;
}
const mySchema = schema
.object({
email: schema.string().strict().trim().email().required(),
name: schema.string().strict().trim().min(1).optional(),
})
.required();
async function main() {
const app = createServer();
// read and parse the input as JSON object with a limit of
// 1 MB (1048576) and validate it with 'mySchema'
// 👇 👇
app.put("/", [json(1), validate(mySchema)], async (request, response) => {
const body: IMySchema = request.body;
response.write("Your input: " + JSON.stringify(body));
});
await app.listen();
}
main().catch(console.error);lang() - Setup current request language [↑]
import createServer, { lang } from "@egomobile/http-server";
async function main() {
const app = createServer();
// setup languages 'de' and 'en', by using the first one
// as default / fallback language
//
// the middleware will extract the value from 'Accept-Language'
// HTTP header and pick up the best matching language from argument list
// by quality value and write it to 'lang' property of 'request'
// 👇
app.post("/", [lang("de", "en")], async (request, response) => {
const lang = request.lang as string; // 'de' or 'en'
response.write("Current language: " + lang);
});
await app.listen();
}
main().catch(console.error);apiKey() - Check for an API key [↑]
import createServer, { apiKey } from "@egomobile/http-server";
async function main() {
const app = createServer();
// checks if x-api-key HTTP header
// contains "mySecret@piKey1234"
app.get(
"/secret-content",
[apiKey("mySecret@piKey1234")],
async (request, response) => {
// your code
}
);
await app.listen();
}
main().catch(console.error);auth() - Check Authorization header [↑]
import createServer, {
auth,
AuthValidatorWithoutScheme,
IHttpRequest,
IHttpResponse,
} from "@egomobile/http-server";
const checkBearer: AuthValidatorWithoutScheme = async (
value: string,
request: IHttpRequest,
response: IHttpResponse
) => {
// client must submit something like
// 'Authorization: Bearer myBearerValue'
return value === "myBearerValue";
};
async function main() {
const app = createServer();
// check if authorization header uses 'Bearer' scheme
// and its value matches all criteria of 'checkBearer()'
app.get("/", auth("Bearer", checkBearer), async (response, response) => {
// your code, if bearer value is valid
});
await app.listen();
}
main().catch(console.error);basicAuth() - Check username and password [↑]
import createServer, {
basicAuth,
BasicAuthCredentials,
IHttpRequest,
IHttpResponse,
} from "@egomobile/http-server";
const usersAndPasswords: BasicAuthCredentials = {
bill: "B@zPasswd$",
marcel: "fooPassword",
tanja: "barPasswd1234",
};
async function main() {
const app = createServer();
app.get(
"/",
basicAuth(usersAndPasswords),
async (response: IHttpRequest, response: IHttpResponse) => {
// your code, if credentials are valid
}
);
await app.listen();
}
main().catch(console.error);validateWithSwagger() - Validate request with Swagger [↑]
import createServer, { query, validateWithSwagger } from '@egomobile/http-server'
import type { OpenAPIV3.OperationObject } from 'openapi-types'
const swaggerDocumentOfGetRequest: OpenAPIV3.OperationObject = {
"parameters": [
{
in: 'query',
name: 'foo',
required: true
},
"responses": {}
]
}
const app = createServer()
app.get(
'/',
[
query(),
validateWithSwagger(swaggerDocumentOfGetRequest)
],
async (request, response) => {
assert.strictEqual(typeof request.query!.get('foo'), 'string')
}
)
// ...licensed under GDFL 1.3 - © Next.e.GO Mobile SE