Options
All
  • Public
  • Public/Protected
  • All
Menu

Class App

import App from 'u-http-server';

This class let you create http, https, http2 builtin node server with simple api for middleware and routing.

The api of this class is close to express or koa for easy adoption but all your routes or middlewares are handling in async await manner.

instances of App have two separate stack, one for middlewares, the other for routes.

  • use() place in middlewares stack
  • route() and shortcut (get(), post(), etc.) place in routes stack

They both have same syntax and called in the same way

Lyfecycle of a request

When a server recieve a request, midlewares stack and routes stack are merged (middlewares first, next routes) in order they were declared

Iterate on this merge. If methods and route match:

  • params are populated for route (/:categorie/:item => /cheese/camembert => {categorie: 'cheese', item: 'camenbert'})
  • middleware will be called in async way : lastResult = await middleware(ctx, lastResult);
  • When it terminate:
    • if response.finished break loop
    • else continue with next middleware in stack until no more middleware to handle.

Next to last middleware, if not response.finished: response.end(typeof lastResult === 'object' ? JSON.stringify(lastResult) : lastResult.toString()); It's for avoiding server never respond to client (and keep open ressources for nothing). And in your route, if you wan't return some data, you can. instead of calling yourself response.end(data) or response.end(JSON.stringify(data))

/!\ For avoiding race exceptions, be sure when your middleware end, it has not open some asynchronous things not awaited. If you need to use some async api working with callback, wrap it in a Promise, resolve (or reject) it in callback and await or return this Promise.

example

Some examples below

Basic

import App, {parseCookie, sessionInMemory} from 'u-http-server';

const app = new App();

app
 .use(ctx => console.log(ctx.request.url))
 .use(parseCookie)
 .use(sessionInMemory)
 .get('/:category/:page', ctx => ctx.response.end(JSON.stringify(ctx.params)))
 .get('/:test', ctx => ctx.response.end(JSON.stringify(ctx.params)))
 .route(ctx => ctx.response.end('Hello World !'))

app.init({protocol: 'http2', selfSigned: true})
 .then(app => app.applyOnClientError())
 .then(app => app.listen(3000))
 .then(url => console.log('server listening on', url));

lastReturn mechanism

import fetch from 'node-fetch';
import RSS from 'rss';
import format from 'date-fns/format/index.js';

const hytale_list = 'https://hytale.com/api/blog/post/published';
const hytale_article = 'https://hytale.com/api/blog/post/slug/';

const hytale_feed = feed_url => ({
 'title': 'Hytale',
 'description': 'News from Hytale',
 'feed_url': feed_url,
 'site_url': 'https://hytale.com/news',
 'image_url': 'https://hytale.com/static/images/logo.png',
});

const getArticleUrl = item => `https://hytale.com/news/${format(item.createdAt, 'yyyy/MM')}/${item.slug}`;

// fetch articles list from hytale api
app.get('/rss/hytale', async ctx => {
 const articles_resume = await fetch(hytale_list).then(r => r.json());

 return Promise.all(
   articles_resume.map(a => fetch(hytale_article + a.slug).then(r => r.json()))
 );
});

// transform in to a rss feed
app.get('/rss/hytale', (ctx, articles) => articles.reduce((feed, item) => feed.item({
  title: item.title,
  description: item.body,
  url: getArticleUrl(item),
  guid: `${item.slug}-${item._id}`,
  categories: item.tags,
  author: item.author,
  date: item.publishedAt,
  enclosure: {
    url: `https://hytale.com/m/variants/blog_cover_${item.coverImage.s3Key}`,
    type: item.coverImage.mimeType,
  }
}), new RSS(hytale_feed(`${app.address}${ctx.request.url.toString()}`))).xml({indent: true}));

// set content-type and end response with generated rss feed
app.get('/rss/:flux', (ctx, rss) => {
 ctx.response.setHeader('Content-Type', 'application/rss+xml');
 ctx.response.end(rss);
});

Hierarchy

  • App

Index

Type aliases

Static Method

Method: "GET" | "POST" | "HEAD" | "PUT" | "PATCH" | "DELETE" | "ACL" | "BIND" | "CHECKOUT" | "CONNECT" | "COPY" | "LINK" | "LOCK" | "M-SEARCH" | "MERGE" | "MKACTIVITY" | "MKCALENDAR" | "MKCOL" | "MOVE" | "NOTIFY" | "OPTIONS" | "PROPFIND" | "PROPPATCH" | "PURGE" | "REBIND" | "REPORT" | "SEARCH" | "SOURCE" | "SUBSCRIBE" | "TRACE" | "UNBIND" | "UNLINK" | "UNLOCK" | "UNSUBSCRIBE"

All http methods supported by Node.js

Static Methods

Methods: Method | Method[]

Static Middleware

Middleware: function

Your callback middleware will be called with ctx and lastResult.

Will be await by the request handler and use the resolved result as lastResult for the next middleware call

Type declaration

    • (ctx: Context, lastResult?: any): Promise<any>
    • Parameters

      • ctx: Context
      • Optional lastResult: any

      Returns Promise<any>

Static ReturnPUse

ReturnPUse: [string[], Return, Middleware]

It's for internal use only

private _use( method support the overloading and normalyze it into the complete signature.

Static Route

Route: string | RegExp | Return

A route can be either :

You are encouraged to use string Route.

'/:category/:page/' will provide you a params object with categories and page key in Context

Properties

Private Optional _isSecure

_isSecure: boolean

Private _middlewares

_middlewares: MiddlewareItem[]

Private _routes

_routes: MiddlewareItem[]

Private Optional _server

_server: Server

Optional address

address: string

populate next to call await app.listen() with server url

readonly

Methods

Private _use

applyOnClientError

  • applyOnClientError(callback?: function): this
  • if no callback provided it will use

    (err, socket) => socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');

    Parameters

    Returns this

delete

  • example
     app.delete(middleware); // equiv to app.delete(/^\/.*$/, middleware);
     app.delete(route, middleware); // equiv to app.route(['DELETE'], route, middleware)

    Parameters

    Returns this

  • Parameters

    Returns this

get

  • example
     app.get(middleware); // equiv to app.get(/^\/.*$/, middleware);
     app.get(route, middleware); // equiv to app.route(['GET'], route, middleware)

    Parameters

    Returns this

  • Parameters

    Returns this

init

  • Init server asynchronously can auto generate self-signed ssl if https or http2

    By default,

    options = {protocol: 'http', selfSigned: false, http2Secure: true}

    If you wan't auto generate self-signed ssl:

    init({protocol: 'https', selfSigned: true})
    // or
    init({protocol: 'http2', selfSigned: true})

    Parameters

    Returns Promise<this>

listen

  • listen(port?: number, host?: string, backlog?: number): Promise<string>
  • listen(options: ListenOptions): Promise<string>
  • Parameters

    • Optional port: number

      if no port provided, os take one available randomly. Think print resolved string url somewhere

    • Optional host: string

      if no provided, 0.0.0.0

    • Optional backlog: number

    Returns Promise<string>

    a string url of server

  • Parameters

    Returns Promise<string>

patch

  • example
     app.patch(middleware); // equiv to app.patch(/^\/.*$/, middleware);
     app.patch(route, middleware); // equiv to app.route(['PATCH'], route, middleware)

    Parameters

    Returns this

  • Parameters

    Returns this

post

  • example
     app.post(middleware); // equiv to app.post(/^\/.*$/, middleware);
     app.post(route, middleware); // equiv to app.route(['POST'], route, middleware)

    Parameters

    Returns this

  • Parameters

    Returns this

put

  • example
     app.put(middleware); // equiv to app.put(/^\/.*$/, middleware);
     app.put(route, middleware); // equiv to app.route(['PUT'], route, middleware)

    Parameters

    Returns this

  • Parameters

    Returns this

route

  • Transform into a MiddlewareItem and put it in _routes stack

    example
     app.route(middleware); // equiv to app.use(http.METHODS, /^\/.*$/, middleware);
     app.route(route, middleware); // equiv to app.use(http.METHODS, route, middleware);
     app.route(methods, route, middleware);

    Parameters

    Returns this

  • Parameters

    Returns this

  • Parameters

    Returns this

use

  • Transform into a MiddlewareItem and put it in _middlewares stack

    example
     app.use(middleware); // equiv to app.use(http.METHODS, /^\/.*$/, middleware);
     app.use(route, middleware); // equiv to app.use(methods, route, middleware);
     app.use(methods, route, middleware);

    Parameters

    Returns this

  • Parameters

    Returns this

  • Parameters

    Returns this

Generated using TypeDoc