Skip to content

Commit

Permalink
Allow routes to define some payload config values
Browse files Browse the repository at this point in the history
  • Loading branch information
afharo committed Nov 15, 2019
1 parent 504604a commit 7cbea0c
Show file tree
Hide file tree
Showing 29 changed files with 244 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Register a route handler for `DELETE` request.
<b>Signature:</b>

```typescript
delete: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B>, handler: RequestHandler<P, Q, B>) => void;
delete: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B, 'delete'>, handler: RequestHandler<P, Q, B>) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Register a route handler for `GET` request.
<b>Signature:</b>

```typescript
get: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B>, handler: RequestHandler<P, Q, B>) => void;
get: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B, 'get'>, handler: RequestHandler<P, Q, B>) => void;
```
8 changes: 4 additions & 4 deletions docs/development/core/server/kibana-plugin-server.irouter.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export interface IRouter

| Property | Type | Description |
| --- | --- | --- |
| [delete](./kibana-plugin-server.irouter.delete.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>DELETE</code> request. |
| [get](./kibana-plugin-server.irouter.get.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>GET</code> request. |
| [post](./kibana-plugin-server.irouter.post.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>POST</code> request. |
| [put](./kibana-plugin-server.irouter.put.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>PUT</code> request. |
| [delete](./kibana-plugin-server.irouter.delete.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B, 'delete'&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>DELETE</code> request. |
| [get](./kibana-plugin-server.irouter.get.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B, 'get'&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>GET</code> request. |
| [post](./kibana-plugin-server.irouter.post.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B, 'post'&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>POST</code> request. |
| [put](./kibana-plugin-server.irouter.put.md) | <code>&lt;P extends ObjectType, Q extends ObjectType, B extends ObjectType&gt;(route: RouteConfig&lt;P, Q, B, 'put'&gt;, handler: RequestHandler&lt;P, Q, B&gt;) =&gt; void</code> | Register a route handler for <code>PUT</code> request. |
| [routerPath](./kibana-plugin-server.irouter.routerpath.md) | <code>string</code> | Resulted path |

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Register a route handler for `POST` request.
<b>Signature:</b>

```typescript
post: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B>, handler: RequestHandler<P, Q, B>) => void;
post: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B, 'post'>, handler: RequestHandler<P, Q, B>) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Register a route handler for `PUT` request.
<b>Signature:</b>

```typescript
put: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B>, handler: RequestHandler<P, Q, B>) => void;
put: <P extends ObjectType, Q extends ObjectType, B extends ObjectType>(route: RouteConfig<P, Q, B, 'put'>, handler: RequestHandler<P, Q, B>) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export declare class KibanaRequest<Params = unknown, Query = unknown, Body = unk
| [headers](./kibana-plugin-server.kibanarequest.headers.md) | | <code>Headers</code> | Readonly copy of incoming request headers. |
| [params](./kibana-plugin-server.kibanarequest.params.md) | | <code>Params</code> | |
| [query](./kibana-plugin-server.kibanarequest.query.md) | | <code>Query</code> | |
| [route](./kibana-plugin-server.kibanarequest.route.md) | | <code>RecursiveReadonly&lt;KibanaRequestRoute&gt;</code> | matched route details |
| [route](./kibana-plugin-server.kibanarequest.route.md) | | <code>RecursiveReadonly&lt;KibanaRequestRoute&lt;RouteMethod &#124; 'patch' &#124; 'options'&gt;&gt;</code> | matched route details |
| [socket](./kibana-plugin-server.kibanarequest.socket.md) | | <code>IKibanaSocket</code> | |
| [url](./kibana-plugin-server.kibanarequest.url.md) | | <code>Url</code> | a WHATWG URL standard object. |

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ matched route details
<b>Signature:</b>

```typescript
readonly route: RecursiveReadonly<KibanaRequestRoute>;
readonly route: RecursiveReadonly<KibanaRequestRoute<RouteMethod | 'patch' | 'options'>>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Request specific route information exposed to a handler.
<b>Signature:</b>

```typescript
export interface KibanaRequestRoute
export interface KibanaRequestRoute<Method extends RouteMethod | 'patch' | 'options'>
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [method](./kibana-plugin-server.kibanarequestroute.method.md) | <code>RouteMethod &#124; 'patch' &#124; 'options'</code> | |
| [options](./kibana-plugin-server.kibanarequestroute.options.md) | <code>Required&lt;RouteConfigOptions&gt;</code> | |
| [method](./kibana-plugin-server.kibanarequestroute.method.md) | <code>Method</code> | |
| [options](./kibana-plugin-server.kibanarequestroute.options.md) | <code>Method extends 'get' ? Required&lt;Pick&lt;RouteConfigOptions&lt;Method&gt;, 'authRequired' &#124; 'tags'&gt;&gt; : Required&lt;RouteConfigOptions&gt;</code> | |
| [path](./kibana-plugin-server.kibanarequestroute.path.md) | <code>string</code> | |

Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
<b>Signature:</b>

```typescript
method: RouteMethod | 'patch' | 'options';
method: Method;
```
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
<b>Signature:</b>

```typescript
options: Required<RouteConfigOptions>;
options: Method extends 'get' ? Required<Pick<RouteConfigOptions<Method>, 'authRequired' | 'tags'>> : Required<RouteConfigOptions>;
```
1 change: 1 addition & 0 deletions docs/development/core/server/kibana-plugin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ResponseError](./kibana-plugin-server.responseerror.md) | Error message and optional data send to the client in case of error. |
| [ResponseErrorAttributes](./kibana-plugin-server.responseerrorattributes.md) | Additional data to provide error details. |
| [ResponseHeaders](./kibana-plugin-server.responseheaders.md) | Http response headers to set. |
| [RouteContentType](./kibana-plugin-server.routecontenttype.md) | The set of supported parseable Content-Types |
| [RouteMethod](./kibana-plugin-server.routemethod.md) | The set of common HTTP methods supported by Kibana routing. |
| [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | Type definition for a Saved Object attribute value |
| [SavedObjectAttributeSingle](./kibana-plugin-server.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Route specific configuration.
<b>Signature:</b>

```typescript
export interface RouteConfig<P extends ObjectType, Q extends ObjectType, B extends ObjectType>
export interface RouteConfig<P extends ObjectType, Q extends ObjectType, B extends ObjectType, Method extends RouteMethod>
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [options](./kibana-plugin-server.routeconfig.options.md) | <code>RouteConfigOptions</code> | Additional route options [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md)<!-- -->. |
| [options](./kibana-plugin-server.routeconfig.options.md) | <code>RouteConfigOptions&lt;Method&gt;</code> | Additional route options [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md)<!-- -->. |
| [path](./kibana-plugin-server.routeconfig.path.md) | <code>string</code> | The endpoint \_within\_ the router path to register the route. |
| [validate](./kibana-plugin-server.routeconfig.validate.md) | <code>RouteSchemas&lt;P, Q, B&gt; &#124; false</code> | A schema created with <code>@kbn/config-schema</code> that every request will be validated against. |

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Additional route options [RouteConfigOptions](./kibana-plugin-server.routeconfig
<b>Signature:</b>

```typescript
options?: RouteConfigOptions;
options?: RouteConfigOptions<Method>;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) &gt; [accepts](./kibana-plugin-server.routeconfigoptions.accepts.md)

## RouteConfigOptions.accepts property

Default value: allows parsing of the following mime types: \* application/json \* application/\*+json \* application/octet-stream \* application/x-www-form-urlencoded \* multipart/form-data \* text/\* A string or an array of strings with the allowed mime types for the endpoint. Use this settings to limit the set of allowed mime types. Note that allowing additional mime types not listed above will not enable them to be parsed, and if parse is true, the request will result in an error response.

<b>Signature:</b>

```typescript
accepts?: Method extends 'get' ? never : RouteContentType | RouteContentType[] | string | string[];
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) &gt; [maxBytes](./kibana-plugin-server.routeconfigoptions.maxbytes.md)

## RouteConfigOptions.maxBytes property

Default value: The one set in the kibana.yml config file under the parameter `server.maxPayloadBytes`<!-- -->. Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory.

<b>Signature:</b>

```typescript
maxBytes?: Method extends 'get' ? never : number;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ Additional route options.
<b>Signature:</b>

```typescript
export interface RouteConfigOptions
export interface RouteConfigOptions<Method extends RouteMethod = any>
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [accepts](./kibana-plugin-server.routeconfigoptions.accepts.md) | <code>Method extends 'get' ? never : RouteContentType &#124; RouteContentType[] &#124; string &#124; string[]</code> | Default value: allows parsing of the following mime types: \* application/json \* application/\*+json \* application/octet-stream \* application/x-www-form-urlencoded \* multipart/form-data \* text/\* A string or an array of strings with the allowed mime types for the endpoint. Use this settings to limit the set of allowed mime types. Note that allowing additional mime types not listed above will not enable them to be parsed, and if parse is true, the request will result in an error response. |
| [authRequired](./kibana-plugin-server.routeconfigoptions.authrequired.md) | <code>boolean</code> | A flag shows that authentication for a route: <code>enabled</code> when true <code>disabled</code> when false<!-- -->Enabled by default. |
| [maxBytes](./kibana-plugin-server.routeconfigoptions.maxbytes.md) | <code>Method extends 'get' ? never : number</code> | Default value: The one set in the kibana.yml config file under the parameter <code>server.maxPayloadBytes</code>. Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory. |
| [output](./kibana-plugin-server.routeconfigoptions.output.md) | <code>Method extends 'get' ? never : 'data' &#124; 'stream' &#124; 'file'</code> | Default value: 'data'. The processed payload format. The value must be one of: \* 'data' - the incoming payload is read fully into memory. If parse is true, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' header. If parse is false, a raw Buffer is returned. \* 'stream' - the incoming payload is made available via a Stream.Readable interface. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files are provided as streams. File streams from a 'multipart/form-data' upload will also have a hapi property containing the filename and headers properties. Note that payload streams for multipart payloads are a synthetic interface created on top of the entire mutlipart content loaded into memory. To avoid loading large multipart payloads into memory, set parse to false and handle the multipart payload in the handler using a streaming parser (e.g. pez). \* 'file' - the incoming payload is written to temporary file in the directory specified by the uploads settings. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files are saved to disk. Note that it is the sole responsibility of the application to clean up the files generated by the framework. This can be done by keeping track of which files are used (e.g. using the request.app object), and listening to the server 'response' event to perform cleanup. |
| [parse](./kibana-plugin-server.routeconfigoptions.parse.md) | <code>Method extends 'get' ? never : boolean &#124; 'gunzip'</code> | Default value: true. Determines if the incoming payload is processed or presented raw. Available values: \* true - if the request 'Content-Type' matches the allowed mime types set by allow (for the whole payload as well as parts), the payload is converted into an object when possible. If the format is unknown, a Bad Request (400) error response is sent. Any known content encoding is decoded. \* false - the raw payload is returned unmodified. \* 'gunzip' - the raw payload is returned unmodified after any known content encoding is decoded. |
| [tags](./kibana-plugin-server.routeconfigoptions.tags.md) | <code>readonly string[]</code> | Additional metadata tag strings to attach to the route. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) &gt; [output](./kibana-plugin-server.routeconfigoptions.output.md)

## RouteConfigOptions.output property

Default value: 'data'. The processed payload format. The value must be one of: \* 'data' - the incoming payload is read fully into memory. If parse is true, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' header. If parse is false, a raw Buffer is returned. \* 'stream' - the incoming payload is made available via a Stream.Readable interface. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files are provided as streams. File streams from a 'multipart/form-data' upload will also have a hapi property containing the filename and headers properties. Note that payload streams for multipart payloads are a synthetic interface created on top of the entire mutlipart content loaded into memory. To avoid loading large multipart payloads into memory, set parse to false and handle the multipart payload in the handler using a streaming parser (e.g. pez). \* 'file' - the incoming payload is written to temporary file in the directory specified by the uploads settings. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files are saved to disk. Note that it is the sole responsibility of the application to clean up the files generated by the framework. This can be done by keeping track of which files are used (e.g. using the request.app object), and listening to the server 'response' event to perform cleanup.

<b>Signature:</b>

```typescript
output?: Method extends 'get' ? never : 'data' | 'stream' | 'file';
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) &gt; [parse](./kibana-plugin-server.routeconfigoptions.parse.md)

## RouteConfigOptions.parse property

Default value: true. Determines if the incoming payload is processed or presented raw. Available values: \* true - if the request 'Content-Type' matches the allowed mime types set by allow (for the whole payload as well as parts), the payload is converted into an object when possible. If the format is unknown, a Bad Request (400) error response is sent. Any known content encoding is decoded. \* false - the raw payload is returned unmodified. \* 'gunzip' - the raw payload is returned unmodified after any known content encoding is decoded.

<b>Signature:</b>

```typescript
parse?: Method extends 'get' ? never : boolean | 'gunzip';
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [RouteContentType](./kibana-plugin-server.routecontenttype.md)

## RouteContentType type

The set of supported parseable Content-Types

<b>Signature:</b>

```typescript
export declare type RouteContentType = 'application/json' | 'application/*+json' | 'application/octec-stream' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/*';
```
32 changes: 32 additions & 0 deletions src/core/server/http/http_server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,38 @@ test('exposes route details of incoming request to a route handler', async () =>
});
});

test('exposes route details of incoming request to a route handler (POST + payload options)', async () => {
const { registerRouter, server: innerServer } = await server.setup(config);

const router = new Router('', logger, enhanceWithContext);
router.post(
{
path: '/',
validate: false,
options: { accepts: 'application/json' },
},
(context, req, res) => res.ok({ body: req.route })
);
registerRouter(router);

await server.start();
await supertest(innerServer.listener)
.post('/')
.send({ test: 1 })
.expect(200, {
method: 'post',
path: '/',
options: {
authRequired: true,
tags: [],
parse: true, // hapi populates the default
maxBytes: 1024, // hapi populates the default
accepts: ['application/json'],
output: 'data',
},
});
});

describe('setup contract', () => {
describe('#createSessionStorage', () => {
it('creates session storage factory', async () => {
Expand Down
Loading

0 comments on commit 7cbea0c

Please sign in to comment.