Koa
Koa is a very lightweight and easy-to-use Web framework. The content of this chapter mainly introduces how to use Koa as the upper-level framework in Midway and use its own capabilities.
Midway's default examples are based on this package.
The @midwayjs/koa
package uses koa @2
and integrates @koa/router
as the basic routing capability by default, and has built-in session
and body-parser
functions by default.
Description | |
---|---|
Contains independent main framework | ✅ |
Contains independent logs | ✅ |
Installation dependency
$ npm i @midwayjs/koa@3 --save
Or reinstall the following dependencies in package.json
.
{
"dependencies": {
"@midwayjs/koa": "^3.0.0",
// ...
},
}
Examples can also be created directly using scaffolding.
# npm v6
$ npm init midway --type=koa-v3 my_project
# npm v7
$ npm init midway -- --type=koa-v3 my_project
Enable component
import { Configuration, App } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import { join } from 'path';
@Configuration({
imports: [koa]
importConfigs: [join(__dirname, './config')]
})
export class MainConfiguration {
@App()
app: koa.Application;
async onReady() {
// ...
}
}
BodyParser
@midwayjs/koa
has its own bodyParser
function, which will parse Post
requests by default and automatically recognize json
and form
types.
If you need text or xml, you can configure it yourself.
The default size is limited to 1mb
. You can set the size of each item separately.
// src/config/config.default
export default {
// ...
bodyParser: {
enableTypes: ['json', 'form', 'text', 'xml']
formLimit: '1mb',
jsonLimit: '1mb',
textLimit: '1mb',
xmlLimit: '1mb',
},
}
Note that the type selection when using Postman for Post requests:
Disable bodyParser middleware。
// src/config/config.default
export default {
// ...
bodyParser: {
enable: false,
// ...
},
}
Cookie and Session
@midwayjs/koa
encapsulates cookies
parsing and Session
support by default. You can view Cookies and Session.
Extended Context
In some scenarios, the Context needs to be expanded.
If you want to hang some temporary request-related object data, you can use the ctx.setAttr(key, value)
API to implement it, such as the data used by the component.
If you really want to extend the Context, you can use koa's own API.
For example, we extend in configuration.ts
to provide a render()
method.
import { App, Configuration } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
@Configuration({
// ...
})
export class MainConfiguration {
@App()
app: koa.Application;
async onReady(container) {
Object.defineProperties(app.context, {
render: {
value: async function (...args) {
// ...
},
},
});
}
}
However, this cannot directly allow the Context to include Typescript Definitions. Additional definitions are required. Please refer to extended context definitions.
Get Http Server
In some special cases, you need to get the original Http Server, we can get it after the server starts.
import { App, Configuration } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
@Configuration({
// ...
})
export class MainConfiguration {
@Inject()
framework: koa.Framework;
async onServerReady(container) {
const server = this.framework.getServer();
// ...
}
}
State type definition
There is a special State attribute in koa's Context, and the State definition can be extended in a similar way to Context.
// src/interface.ts
declare module '@midwayjs/koa/dist/interface' {
interface Context {
abc: string;
}
interface State{
bbb: string;
ccc: number;
}
}
Configuration
Default configuration
The configuration sample of @midwayjs/Koa
is as follows:
// src/config/config.default
export default {
// ...
koa: {
port: 7001
},
}
All attributes are described as follows:
Property | Type | Description |
---|---|---|
port | Number | Optional, port to start |
globalPrefix | string | optional. the global http prefix |
keys | string[] | Optional, Cookies signature, if the upper layer does not write keys, you can also set it here |
hostname | string | Optional. The hostname to listen to. Default 127.1 |
Key | string | Buffer | Array<Buffer|Object> | Optional, Https key, server private key |
cert | string | Buffer | Array<Buffer|Object> | Optional, Https cert, server certificate |
ca | string | Buffer | Array<Buffer|Object> | Optional, Https ca |
http2 | boolean | Optional, supported by http2, default false |
proxy | boolean | Optional, whether to enable the proxy. If it is true, the IP in the request request will be obtained first from the X-Forwarded-For in the Header field. The default is false. |
subdomainOffset | number | optional, the offset of the subdomain name, default 2. |
proxyIpHeader | string | optional. obtains the field name of the proxy ip address. the default value is X-Forwarded-For |
maxIpsCount | number | optional. the maximum number of ips obtained, which is 0 by default. |
serverTimeout | number | Optional, server timeout configuration, the default is 2 60 1000 (2 minutes), in milliseconds |
serverOptions | Record<string, any> | Optional,http Server Options |
Modify port
By default, we provide the 7001
default port parameter in config.default
. by modifying it, we can modify the default port of koa http service.
For example, we changed it to 6001
:
// src/config/config.default
export default {
// ...
koa: {
port: 6001
},
}
By default, our port configuration is null
because the single-test environment requires supertest to start the port.
// src/config/config.unittest
export default {
// ...
koa: {
port: null
},
}
In addition, you can also temporarily modify the port by midway-bin dev-ts-port = 6001
, which overwrites the configured port.
Global prefix
For more information about this feature, see [Global Prefixes](../controller# Global Routing Prefix).
Reverse proxy configuration
If you use a reverse proxy such as Nginx, please enable the proxy
configuration.
// src/config/config.default
export default {
// ...
koa: {
proxy: true,
},
}
The X-Forwarded-For
Header is used by default. If the proxy configuration is different, please configure a different Header yourself.
// src/config/config.default
export default {
// ...
koa: {
proxy: true,
proxyIpHeader: 'X-Forwarded-Host'
},
}
Https configuration
In most cases, please use external agents as much as possible to complete the implementation of Https, such as Nginx.
In some special scenarios, you can directly turn on Https by configuring SSL certificates (TLS certificates).
First, you must prepare certificate files in advance, such as ssl.key
and ssl.pem
. The key is the private key of the server and the pem is the corresponding certificate.
Then configure it.
// src/config/config.default
import { readFileSync } from 'fs';
import { join } from 'path';
export default {
// ...
koa: {
key: join(__dirname, '../ssl/ssl.key')
cert: join(__dirname, '../ssl/ssl.pem')
},
}
favicon settings
By default, the browser will initiate a request to favicon.ico
.
The framework provides a default middleware to handle the request, and you can specify a favicon
Buffer.
// src/config/config.default
import { readFileSync } from 'fs';
import { join } from 'path';
export default {
// ...
siteFile: {
favicon: readFileSync(join(__dirname, '../static/fav.ico'))
},
}
If the @midwayjs/static-file
component is turned on, static file hosting of the component will be preferred.
Disable middleware。
// src/config/config.default
export default {
// ...
siteFile: {
enable: false,
// ...
},
}
Modify context log
The context log of the koa framework can be modified separately.
export default {
koa: {
contextLoggerFormat: info => {
const ctx = info.ctx;
return '${info.timestamp} ${info.LEVEL} ${info.pid} [${ctx.userId} - ${Date.now() - ctx.startTime}ms ${ctx.method}] ${info.message}';
}
// ...
},
};
Query array parsing
By default, koa uses querystring
to parse query parameters, and when it encounters an array, it will split the data in the array.
for example:
GET /query?a[0]=1&a[1]=2
The result obtained is:
{
"a[0]": 1,
"a[1]": 2,
}
The framework provides some parameters to handle this situation.
// src/config/config.default
export default {
// ...
koa: {
queryParseMode: 'extended',
// ...
},
}
The queryParseMode
parameter can choose from three values: extended
, strict
, and first
.
When queryParseMode
has a value, the qs
module will be used to process the query, and the effect is the same as the koa-qs
module.
When the request parameter is /query?a=1&b=2&a=3&c[0]=1&c[1]=2'
.
Default effect (using querystring
)
{
"a": ["1", "3" ],
"b": "2",
"c[0]": "1",
"c[1]": "2"
}
extended
effect
{
"a": ["1", "3" ],
"b": ["2"],
"c": ["1", "2"]
}
strict
effect
{
"a": ["1", "3" ],
"b": "2",
"c": ["1", "2"]
}
first
effect
{
"a": "1",
"b": "2",
"c": "1"
}
### Timeout Configuration
RequestTimeout and ServerTimeout are two different timeout scenarios.
- `serverTimeout`: Used to set the timeout for the server to wait for the client to send data after receiving a request. If the client does not send any data within this time, the server will close the connection. This timeout applies to the entire request-response cycle, including request headers, request body, and response.
- `requestTimeout`: Used to set the timeout for the server to wait for the client to send a complete request. This timeout applies specifically to request headers and request body. If the complete request is not received within this time, the server will abort the request.
By default, `serverTimeout` is set to 0 and does not trigger a timeout.
If needed, you can modify the configuration by specifying the timeout in milliseconds.
```typescript
// src/config/config.default
export default {
// ...
koa: {
serverTimeout: 100_000
},
}
If you encounter the ERR_HTTP_REQUEST_TIMEOUT
error, it means that the requestTimeout
has been triggered, which defaults to 300_000
(5 minutes) in milliseconds. You can modify this timeout by configuring as follows.
// src/config/config.default
export default {
// ...
koa: {
serverOptions: {
requestTimeout: 600_000
}
},
}