mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Docs] Added OAS dev tutorial (#187573)
## Summary
<details>
<summary>Screenshot (slightly outdated)</summary>

</detials>
This commit is contained in:
parent
3a9b01cf22
commit
9575b3a17e
4 changed files with 188 additions and 4 deletions
178
dev_docs/tutorials/generating_oas_for_http_apis.mdx
Normal file
178
dev_docs/tutorials/generating_oas_for_http_apis.mdx
Normal file
|
@ -0,0 +1,178 @@
|
|||
---
|
||||
id: kibDevTutorialGeneratingOASForHTTPAPIs
|
||||
slug: /kibana-dev-docs/genereating-oas-for-http-apis
|
||||
title: Generating OAS for HTTP APIs
|
||||
description: This tutorial demonstrates how to generate OpenAPI specification for HTTP APIs.
|
||||
date: 2024-07-04
|
||||
tags: ['kibana', 'onboarding', 'dev', 'architecture', 'http', 'rest', 'api']
|
||||
---
|
||||
|
||||
<DocCallOut title="OAS is required for all public routes">
|
||||
If your route declares `access: 'public'` you **must** provide up-to-date OpenAPI specification for it. Docs for these routes get hosted on [on our docs site](https://www.elastic.co/docs/api/doc/serverless) and are used for client integrations. For example: our [Elastic stack terraform provider](https://github.com/elastic/terraform-provider-elasticstack).
|
||||
</DocCallOut>
|
||||
|
||||
### Important components
|
||||
|
||||
To get OAS generated for HTTP APIs you must use the following components:
|
||||
|
||||
1. Core's `router` or `router.versioned` for defining HTTP APIs provided via the `core.http` service to all plugins
|
||||
2. `@kbn/config-schema` request and response schemas, skip to <a href="#what-about-runtime-validation-libary-x">this</a> FAQ for more information
|
||||
|
||||
<DocCallOut title="Beyond runtime validation">
|
||||
Kibana's core platform supports `@kbn/config-schema` as a first-class citizen for various schema purposes: configuration, saved objects, and HTTP API request/response bodies.
|
||||
|
||||
Developers can leverage `@kbn/config-schema` as a single-source of truth for runtime validation, TypeScript interfaces, and OpenAPI specification.
|
||||
</DocCallOut>
|
||||
|
||||
### How do I see my HTTP API's OAS?
|
||||
|
||||
In `kibana.dev.yml` add the following configuration:
|
||||
|
||||
```yaml
|
||||
server.oas.enabled: true
|
||||
```
|
||||
|
||||
Launch Kibana and send the following request:
|
||||
|
||||
```bash
|
||||
curl -s -uelastic:changeme http://localhost:5601/api/oas\?pathStartsWith\=/api/foo
|
||||
```
|
||||
|
||||
The value returned should contain the OpenAPI specification for your route and any other path's start with `/api/foo`.
|
||||
|
||||
Other useful query parameters for filtering are:
|
||||
* `pluginId` - get the OAS for a specific plugin, for example: `@kbn/data-views-plugin`
|
||||
* `access` - filter for specific access levels: `public` or `internal` are supported
|
||||
|
||||
### Some good practices to consider
|
||||
|
||||
#### 1. Runtime schema definitions
|
||||
|
||||
```typescript
|
||||
// In server/schemas/v1.ts
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
|
||||
export const fooResource = schema.object({
|
||||
name: schema.string()
|
||||
// ...and any other fields you may need
|
||||
});
|
||||
|
||||
export type FooResource = TypeOf<typeof fooResource>;
|
||||
|
||||
// In common/foo/v1.ts
|
||||
export type { FooResource } from '../server/schemas/v1';
|
||||
|
||||
// In common/index.ts expose this as the "latest" schema shape
|
||||
export type { FooResource } from './latest';
|
||||
|
||||
export * as fooResourceV1 from '../foo/v1';
|
||||
```
|
||||
|
||||
This example demonstrates how you can organize runtime schemas to prepare for:
|
||||
|
||||
1. Being versioned
|
||||
2. Have TypeScript references available to client and server code in your plugin
|
||||
|
||||
See <DocLink id="kibDevTutorialVersioningInterfaces" text="strategies for versioning your schemas" /> for more information on this organizational pattern.
|
||||
|
||||
#### 2. Route definitions
|
||||
|
||||
```typescript
|
||||
// Somewhere in your plugin's server/routes folder
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import type { FooResource } from '../../../common';
|
||||
import { fooResource } from '../../schemas/v1';
|
||||
|
||||
// Note: this response schema is instantiated lazily to avoid creating schemas that are not needed in most cases!
|
||||
const fooResourceResponse = () => {
|
||||
return schema.object({
|
||||
id: schema.string({ maxLength: 20 }),
|
||||
name: schema.string(),
|
||||
createdAt: schema.string(),
|
||||
})
|
||||
}
|
||||
|
||||
// Note: TypeOf can extract types for lazily instantiated schemas
|
||||
type FooResourceResponse = TypeOf<typeof fooResourceResponse>
|
||||
|
||||
function registerFooRoute(router: IRouter, docLinks: DoclinksStart) {
|
||||
router.versioned
|
||||
.post({
|
||||
path: '/api/foo',
|
||||
access: 'public',
|
||||
summary: 'Create a foo resource'
|
||||
description: `A foo resource enables baz. See the following [documentation](${docLinks.links.fooResource}).`,
|
||||
})
|
||||
.addVersion({
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: {
|
||||
body: ,
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
body: fooResourceResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async (ctx, req, res) => {
|
||||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const body = req.body;
|
||||
const foo = await createFoo({ name: body.name });
|
||||
// This is our HTTP translation layer to ensure only the necessary fields included
|
||||
const responseBody: FooResourceResponse = {
|
||||
id: foo.id,
|
||||
name: foo.name,
|
||||
createdAt: foo.createdAt,
|
||||
};
|
||||
return res.ok({ body: responseBody });
|
||||
}
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Generating OAS
|
||||
|
||||
See <a href="#how-do-i-see-my-http-apis-oas">this section</a> about viewing your HTTP APIs OAS.
|
||||
|
||||
#### 4. Iterating on OAS
|
||||
|
||||
From here, you can develop your route and schema definitions iteratively. After each change the Kibana server will
|
||||
automatically reload and the latest OAS should reflect the current state of your code!
|
||||
|
||||
For example, let's add a few descriptions to our schema members:
|
||||
|
||||
```typescript
|
||||
const fooResourceResponse = () => {
|
||||
return schema.object({
|
||||
id: schema.string({ maxLength: 20, meta: { description: 'An unique ID for a foo resource.'} }),
|
||||
name: schema.string({ meta: { description: 'A human friendly name for a foo resource.'} }),
|
||||
createdAt: schema.string({ meta: { description: 'The ISO date a foo resource was created.'} }),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
This descriptions should now be reflected in the OAS generated for your route.
|
||||
|
||||
#### 5. Publishing OAS
|
||||
|
||||
OAS for public routes are written to the Kibana repo as a snapshot that will ultimately be published.
|
||||
|
||||
<DocCallOut title="Under construction" color="warning">
|
||||
At the time of writing we only capture OAS for a subset of Kibana's HTTP APIs to give teams time to check and improve the quality of generated OAS.
|
||||
|
||||
If you would like OAS for your endpoints to be included in the snapshot, **please reach out to #kibana-core**.
|
||||
</DocCallOut>
|
||||
|
||||
|
||||
### FAQs
|
||||
|
||||
#### What about runtime validation libary X?
|
||||
Teams have adopted different runtime validation libraries for their HTTP APIs. Kibana core does not intend to support all runtime validation libraries.
|
||||
|
||||
Reach out to #kibana-core with questions, concerns or issues you may be facing with `@kbn/config-schema` and we will help you find a solution.
|
||||
|
||||
#### What about internal HTTP APIs?
|
||||
It's possible to generate OpenAPI specification for `access: 'internal'` routes but it is not required. The benefit will largely be for your team's internal reference and for other teams to discover your APIs. If you follow the practices outlined in this tutorial it should be simple to generate OAS for internal routes as well.
|
|
@ -3,7 +3,7 @@ id: kibDevTutorialVersioningHTTPAPIs
|
|||
slug: /kibana-dev-docs/versioning-http-apis
|
||||
title: Versioning HTTP APIs
|
||||
description: This tutorial demonstrates how to create or migrate to versionable HTTP APIs.
|
||||
date: 2023-02-09
|
||||
date: 2024-07-04
|
||||
tags: ['kibana', 'onboarding', 'dev', 'architecture']
|
||||
---
|
||||
|
||||
|
|
|
@ -135,6 +135,9 @@
|
|||
"id": "kibDevTutorialVersioningInterfaces",
|
||||
"label": "Versioning interfaces"
|
||||
},
|
||||
{
|
||||
"id": "kibDevTutorialGeneratingOASForHTTPAPIs"
|
||||
},
|
||||
{
|
||||
"id": "kibDevTutorialSubmitPullRequest"
|
||||
},
|
||||
|
|
|
@ -88,9 +88,12 @@ module.exports = {
|
|||
],
|
||||
"nav": {
|
||||
"structure": [
|
||||
"nav-elastic-developer-guide",
|
||||
"nav-kibana-team",
|
||||
"nav-kibana-dev"
|
||||
{
|
||||
collection: 'Elastic Developer Guide',
|
||||
navs: ['nav-elastic-developer-guide'],
|
||||
},
|
||||
{ collection: 'Kibana Team', navs: ['nav-kibana-team'] },
|
||||
{ collection: 'Kibana Developer Guide', navs: ['nav-kibana-dev'] },
|
||||
],
|
||||
"default": "nav-kibana-dev"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue