liefern
v1.0.0-rc-12
Published
Node Webserver without dependencies
Downloads
23
Maintainers
Readme
liefern.io
Simple, fast and no-dependency web server for nodejs.
Table of Contents
Installation
$ npm install liefern
Quick Start
$ mkdir myapp
$ cd myapp
$ npm init
$ npm install liefern
Examples
Hello World
import { Liefern } from 'liefern'
const server = Liefern()
server.use(({ request, sharedData }) => {
sharedData.requestIp = request.socket.remoteAddress
})
server.get('/', ({ send: { text }, sharedData }) => {
text(`Hello World! (${sharedData.requestIp})`)
})
server.post('/', async ({ send: { text }, body }) => {
console.log(await body())
text('Hello World!')
})
server.start(1337)
Static files
import { Liefern } from 'liefern'
const server = Liefern()
server.static('/', `/absolutPath/to/publicHtml`)
server.start(1337)
Testing with supertest
import { Liefern } from 'liefern'
const server = Liefern({ name: 'TestServer' })
server.get('/', ({ send: { ok }}) => {
ok()
})
await supertest(server.httpServer)
.get('/')
.expect(200)
Features
- [x] routing
- [x] regex url-pattern
- [x] url-pattern-matching customizable
- [x] all-helper for html-verb independed routes
- [x] logging
- [x] customizable
- [x] full async
- [x] exitable by signal
- [x] appendable with middlewares
- [x] shared data (middleware -> controller)
- [x] serving static files
- [x] even with middleware handling
- [x] typescript
- [x] ESM & CJS
- [x] CORS
- [x] helper for incomming request-body (json, text)
- [x] plain node testrunner
Requirements
- node
- we using "node:" protocol imports (https://nodejs.org/api/esm.html#node-imports) so we need a node-version supporting this
- 14.13.1 (if you using "import")
- 16.0.0 (if you use "require")
- we using "node:" protocol imports (https://nodejs.org/api/esm.html#node-imports) so we need a node-version supporting this
Documentation
Liefern
Constructor
new Liefern({
name?: string
logger?: Logger
urlMatcher?: UrlMatcherType
})
.start
const server = new Liefern()
async server.start(8080)
.stop
const server = new Liefern()
async server.start(8080)
async server.stop()
.use
const server = new Liefern()
server.use(({ request, sharedData }) => {
sharedData.requestIp = request.socket.remoteAddress
})
.cors
server.cors({
origin?: string[] | '*',
allowMethods?: string[] | '*',
exposeHeaders?: string[],
allowHeaders?: string[] | '*',
maxAge?: number,
credentials?: boolean,
secureContext?: boolean,
privateNetworkAccess?: boolean
})
.get
server.get('/api/user/(\\d+)', ({ send: { json }, urlParams }) => {
const [userId] = urlParams
json({ testData: true, id: userId })
})
.head
server.head('/', ({ send: { ok }}) => {
ok()
})
.post
server.post('/', ({ send: { ok }}) => {
ok()
})
.put
server.put('/', ({ send: { ok }}) => {
ok()
})
.delete
server.delete('/', ({ send: { ok }}) => {
ok()
})
.patch
server.patch('/', ({ send: { ok }}) => {
ok()
})
.connect
server.connect('/', ({ send: { forbidden }}) => {
forbidden()
})
.trace
server.trace('/', ({ send: { notFound }}) => {
notFound()
})
.options
server.options('/', ({ send: { ok }}) => {
ok()
})
.all
server.all('/', ({ send: { ok }}) => {
ok()
})
Controller
type Controller = (params: ControllerParams) => void | Promise<void>
ControllerParams
type ControllerParams = {
sharedData: SharedObject
request: Request
response: Response
urlParams: UrlParams
statusCode: (statusCode: number) => void
body: undefined | string | JsonType
contentType: {
textHtml: () => void
textPlain: () => void
applicationJson: () => void
}
setHeader: (name: string, value: string | number | readonly string[]) => void
statusCodes: {
ok: () => void
created: () => void
noContent: () => void
movedPermanently: () => void
notModified: () => void
badRequest: () => void
unauthorized: () => void
paymentRequired: () => void
forbidden: () => void
notFound: () => void
internalServerError: () => void
notImplemented: () => void
}
send: {
json: (data: JsonType) => void
text: (data: string) => void
html: (data: string) => void
ok: () => void
created: () => void
noContent: () => void
movedPermanently: (url: string) => void
notModified: () => void
badRequest: () => void
unauthorized: () => void
paymentRequired: () => void
forbidden: () => void
notFound: () => void
methodNotAllow: () => void
internalServerError: () => void
notImplemented: () => void
}
}
UrlMatcherType
type UrlMatcherType = (
url: string,
pattern: string | RegExp,
) => false | UrlParams | Promise<false | UrlParams>
UrlParams
type UrlParams = string[]
SharedObject
type SharedObject = Record<string, unknown> & {
body: undefined | string | JsonType
}
Request
type Request = http.IncomingMessage
Response
type Response = http.ServerResponse<http.IncomingMessage> & {
req: http.IncomingMessage
}