From 6cc51b7ba03da1fe4b37023ac36576e97999dc79 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Fri, 14 Apr 2023 15:39:39 +0200 Subject: [PATCH] docs: Added docs for edge endpoints (#3501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding documentation for the edge endpoints. Also separating request and response schema for our validate endpoint to make clear that we expect a list of strings as input, but yield tokens as output. --------- Co-authored-by: Gastón Fournier Co-authored-by: Thomas Heartman --- src/lib/openapi/index.test.ts | 10 +- src/lib/openapi/index.ts | 6 +- src/lib/openapi/spec/bulk-metrics-schema.ts | 3 + .../openapi/spec/bulk-registration-schema.ts | 27 +++- .../openapi/spec/client-metrics-env-schema.ts | 22 ++- src/lib/openapi/spec/edge-token-schema.ts | 11 ++ src/lib/openapi/spec/index.ts | 3 +- .../openapi/spec/token-string-list-schema.ts | 23 +++ .../spec/validate-edge-tokens-schema.ts | 29 ---- .../spec/validated-edge-tokens-schema.ts | 27 ++++ src/lib/openapi/util/standard-responses.ts | 11 ++ src/lib/routes/edge-api/index.ts | 37 +++-- src/lib/services/edge-service.ts | 4 +- .../__snapshots__/openapi.e2e.test.ts.snap | 152 +++++++++++++++--- 14 files changed, 283 insertions(+), 82 deletions(-) create mode 100644 src/lib/openapi/spec/token-string-list-schema.ts delete mode 100644 src/lib/openapi/spec/validate-edge-tokens-schema.ts create mode 100644 src/lib/openapi/spec/validated-edge-tokens-schema.ts diff --git a/src/lib/openapi/index.test.ts b/src/lib/openapi/index.test.ts index c72527e91e..447b6b09a8 100644 --- a/src/lib/openapi/index.test.ts +++ b/src/lib/openapi/index.test.ts @@ -32,7 +32,7 @@ describe('createOpenApiSchema', () => { createOpenApiSchema({ unleashUrl: 'https://example.com', baseUriPath: '', - }).servers[0].url, + }).servers![0].url, ).toEqual('https://example.com'); }); @@ -41,7 +41,7 @@ describe('createOpenApiSchema', () => { createOpenApiSchema({ unleashUrl: 'https://example.com/demo2', baseUriPath: '/demo2', - }).servers[0].url, + }).servers![0].url, ).toEqual('https://example.com'); }); @@ -50,7 +50,7 @@ describe('createOpenApiSchema', () => { createOpenApiSchema({ unleashUrl: 'https://example.com/demo2', baseUriPath: 'example', - }).servers[0].url, + }).servers![0].url, ).toEqual('https://example.com/demo2'); }); @@ -59,13 +59,13 @@ describe('createOpenApiSchema', () => { createOpenApiSchema({ unleashUrl: 'https://example.com/example/', baseUriPath: 'example', - }).servers[0].url, + }).servers![0].url, ).toEqual('https://example.com'); expect( createOpenApiSchema({ unleashUrl: 'https://example.com/example/', baseUriPath: '/example', - }).servers[0].url, + }).servers![0].url, ).toEqual('https://example.com'); }); }); diff --git a/src/lib/openapi/index.ts b/src/lib/openapi/index.ts index 279a52e6f0..5c92b339e7 100644 --- a/src/lib/openapi/index.ts +++ b/src/lib/openapi/index.ts @@ -109,6 +109,7 @@ import { tagTypeSchema, tagTypesSchema, tagWithVersionSchema, + tokenStringListSchema, tokenUserSchema, uiConfigSchema, updateApiTokenSchema, @@ -123,7 +124,7 @@ import { usersGroupsBaseSchema, usersSchema, usersSearchSchema, - validateEdgeTokensSchema, + validatedEdgeTokensSchema, validatePasswordSchema, validateTagTypeSchema, variantSchema, @@ -293,6 +294,7 @@ export const schemas: UnleashSchemas = { tagTypesSchema, tagWithVersionSchema, tokenUserSchema, + tokenStringListSchema, uiConfigSchema, updateApiTokenSchema, updateFeatureSchema, @@ -307,7 +309,7 @@ export const schemas: UnleashSchemas = { usersGroupsBaseSchema, usersSchema, usersSearchSchema, - validateEdgeTokensSchema, + validatedEdgeTokensSchema, validatePasswordSchema, validateTagTypeSchema, variantSchema, diff --git a/src/lib/openapi/spec/bulk-metrics-schema.ts b/src/lib/openapi/spec/bulk-metrics-schema.ts index fa290268f8..acf7401086 100644 --- a/src/lib/openapi/spec/bulk-metrics-schema.ts +++ b/src/lib/openapi/spec/bulk-metrics-schema.ts @@ -6,6 +6,9 @@ import { clientMetricsEnvSchema } from './client-metrics-env-schema'; export const bulkMetricsSchema = { $id: '#/components/schemas/bulkMetricsSchema', type: 'object', + required: ['applications', 'metrics'], + description: + 'A batch of metrics accumulated by Edge (or other compatible applications). Includes both application registrations as well usage metrics from clients', properties: { applications: { type: 'array', diff --git a/src/lib/openapi/spec/bulk-registration-schema.ts b/src/lib/openapi/spec/bulk-registration-schema.ts index ce8ee1948b..728194fc17 100644 --- a/src/lib/openapi/spec/bulk-registration-schema.ts +++ b/src/lib/openapi/spec/bulk-registration-schema.ts @@ -4,10 +4,13 @@ import { dateSchema } from './date-schema'; export const bulkRegistrationSchema = { $id: '#/components/schemas/bulkRegistrationSchema', type: 'object', - required: ['appName', 'instanceId'], + required: ['appName', 'instanceId', 'environment'], + description: `An application registration. Defines the format POSTed by our server-side SDKs when they're starting up`, properties: { connectVia: { type: 'array', + description: + 'A list of applications this app registration has been registered through. If connected directly to Unleash, this is an empty list. \n This can be used in later visualizations to tell how many levels of proxy or Edge instances our SDKs have connected through', items: { type: 'object', required: ['appName', 'instanceId'], @@ -20,29 +23,51 @@ export const bulkRegistrationSchema = { }, }, }, + example: [ + { appName: 'unleash-edge', instanceId: 'edge-pod-bghzv5' }, + ], }, appName: { + description: + 'The name of the application that is evaluating toggles', type: 'string', + example: 'Ingress load balancer', }, environment: { + description: 'Which environment the application is running in', type: 'string', + example: 'development', }, instanceId: { + description: + 'A [(somewhat) unique identifier](https://docs.getunleash.io/reference/sdks/node#advanced-usage) for the application', type: 'string', + example: 'application-name-dacb1234', }, interval: { + description: + 'How often (in seconds) the application refreshes its features', type: 'number', + example: 10, }, started: { + description: 'The application started at', + example: '1952-03-11T12:00:00.000Z', //GNU Douglas Adams $ref: '#/components/schemas/dateSchema', }, strategies: { + description: + 'Enabled [strategies](https://docs.getunleash.io/reference/activation-strategies) in the application', type: 'array', + example: ['standard', 'gradualRollout'], items: { type: 'string', }, }, sdkVersion: { + description: + 'The version the sdk is running. Typically :', + example: 'unleash-client-java:8.0.0', type: 'string', }, }, diff --git a/src/lib/openapi/spec/client-metrics-env-schema.ts b/src/lib/openapi/spec/client-metrics-env-schema.ts index ed4346f3c6..b449d1cc4e 100644 --- a/src/lib/openapi/spec/client-metrics-env-schema.ts +++ b/src/lib/openapi/spec/client-metrics-env-schema.ts @@ -4,33 +4,53 @@ import { FromSchema } from 'json-schema-to-ts'; export const clientMetricsEnvSchema = { $id: '#/components/schemas/clientMetricsEnvSchema', type: 'object', - required: ['featureName', 'appName'], + required: ['featureName', 'appName', 'environment'], additionalProperties: true, + description: 'Used for reporting feature evaluation results from SDKs', properties: { featureName: { type: 'string', + description: 'Name of the feature checked by the SDK', + example: 'my.special.feature', }, appName: { + description: 'The name of the application the SDK is being used in', type: 'string', + example: 'accounting', }, environment: { + description: 'Which environment the SDK is being used in', type: 'string', + example: 'development', }, timestamp: { + description: + 'The start of the time window these metrics are valid for. The window is 1 hour wide', + example: '1926-05-08T12:00:00.000Z', $ref: '#/components/schemas/dateSchema', }, yes: { + description: 'How many times the toggle evaluated to true', type: 'number', + example: 974, }, no: { + description: 'How many times the toggle evaluated to false', type: 'number', + example: 50, }, variants: { + description: 'How many times each variant was returned', type: 'object', additionalProperties: { type: 'integer', minimum: 0, }, + example: { + variantA: 15, + variantB: 25, + variantC: 5, + }, }, }, components: { diff --git a/src/lib/openapi/spec/edge-token-schema.ts b/src/lib/openapi/spec/edge-token-schema.ts index cfac9e6d0f..4fae34f6d7 100644 --- a/src/lib/openapi/spec/edge-token-schema.ts +++ b/src/lib/openapi/spec/edge-token-schema.ts @@ -6,19 +6,30 @@ export const edgeTokenSchema = { type: 'object', additionalProperties: false, required: ['token', 'projects', 'type'], + description: + 'A representation of a client token, limiting access to [CLIENT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#client-tokens) (used by serverside SDKs) or [FRONTEND](https://docs.getunleash.io/reference/api-tokens-and-client-keys#front-end-tokens) (used by proxy SDKs)', properties: { projects: { + description: + 'The list of projects this token has access to. If the token has access to specific projects they will be listed here. If the token has access to all projects it will be represented as [`*`]', type: 'array', items: { type: 'string', }, + example: ['developerexperience', 'enterprisegrowth'], }, type: { + description: `The [API token](https://docs.getunleash.io/reference/api-tokens-and-client-keys#api-tokens)'s **type**. Unleash supports three different types of API tokens ([ADMIN](https://docs.getunleash.io/reference/api-tokens-and-client-keys#admin-tokens), [CLIENT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#client-tokens), [FRONTEND](https://docs.getunleash.io/reference/api-tokens-and-client-keys#front-end-tokens)). They all have varying access, so when validating a token it's important to know what kind you're dealing with`, type: 'string', enum: Object.values(ApiTokenType), + example: 'client', }, token: { + description: + 'The actual token value. [Unleash API tokens](https://docs.getunleash.io/reference/api-tokens-and-client-keys) are comprised of three parts. :.randomcharacters', type: 'string', + example: + '*:development.5c806b5320c88cf27e81f3e9b97dab298a77d5879316e3c2d806206b', }, }, components: {}, diff --git a/src/lib/openapi/spec/index.ts b/src/lib/openapi/spec/index.ts index 2c6be98221..d9406044ab 100644 --- a/src/lib/openapi/spec/index.ts +++ b/src/lib/openapi/spec/index.ts @@ -108,7 +108,7 @@ export * from './environments-project-schema'; export * from './instance-admin-stats-schema'; export * from './public-signup-tokens-schema'; export * from './upsert-context-field-schema'; -export * from './validate-edge-tokens-schema'; +export * from './validated-edge-tokens-schema'; export * from './client-features-query-schema'; export * from './admin-features-query-schema'; export * from './playground-constraint-schema'; @@ -132,3 +132,4 @@ export * from './import-toggles-schema'; export * from './tags-bulk-add-schema'; export * from './upsert-segment-schema'; export * from './batch-features-schema'; +export * from './token-string-list-schema'; diff --git a/src/lib/openapi/spec/token-string-list-schema.ts b/src/lib/openapi/spec/token-string-list-schema.ts new file mode 100644 index 0000000000..752d32e4c7 --- /dev/null +++ b/src/lib/openapi/spec/token-string-list-schema.ts @@ -0,0 +1,23 @@ +import { FromSchema } from 'json-schema-to-ts'; + +export const tokenStringListSchema = { + $id: '#/components/schemas/tokenStringListSchema', + type: 'object', + additionalProperties: true, + description: 'A list of unleash tokens to validate against known tokens', + required: ['tokens'], + properties: { + tokens: { + description: 'Tokens that we want to get access information about', + type: 'array', + items: { type: 'string' }, + example: [ + 'aproject:development.randomstring', + '[]:production.randomstring', + ], + }, + }, + components: {}, +} as const; + +export type TokenStringListSchema = FromSchema; diff --git a/src/lib/openapi/spec/validate-edge-tokens-schema.ts b/src/lib/openapi/spec/validate-edge-tokens-schema.ts deleted file mode 100644 index 33691f40fb..0000000000 --- a/src/lib/openapi/spec/validate-edge-tokens-schema.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { FromSchema } from 'json-schema-to-ts'; -import { edgeTokenSchema } from './edge-token-schema'; - -export const validateEdgeTokensSchema = { - $id: '#/components/schemas/validateEdgeTokensSchema', - type: 'object', - additionalProperties: false, - required: ['tokens'], - properties: { - tokens: { - type: 'array', - items: { - anyOf: [ - { $ref: '#/components/schemas/edgeTokenSchema' }, - { type: 'string' }, - ], - }, - }, - }, - components: { - schemas: { - edgeTokenSchema, - }, - }, -} as const; - -export type ValidateEdgeTokensSchema = FromSchema< - typeof validateEdgeTokensSchema ->; diff --git a/src/lib/openapi/spec/validated-edge-tokens-schema.ts b/src/lib/openapi/spec/validated-edge-tokens-schema.ts new file mode 100644 index 0000000000..19469ef619 --- /dev/null +++ b/src/lib/openapi/spec/validated-edge-tokens-schema.ts @@ -0,0 +1,27 @@ +import { FromSchema } from 'json-schema-to-ts'; +import { edgeTokenSchema } from './edge-token-schema'; + +export const validatedEdgeTokensSchema = { + $id: '#/components/schemas/validatedEdgeTokensSchema', + type: 'object', + additionalProperties: false, + required: ['tokens'], + description: `A object containing a list of valid Unleash tokens.`, + properties: { + tokens: { + description: + 'The list of Unleash token objects. Each object contains the token itself and some additional metadata.', + type: 'array', + items: { $ref: '#/components/schemas/edgeTokenSchema' }, + }, + }, + components: { + schemas: { + edgeTokenSchema, + }, + }, +} as const; + +export type ValidatedEdgeTokensSchema = FromSchema< + typeof validatedEdgeTokensSchema +>; diff --git a/src/lib/openapi/util/standard-responses.ts b/src/lib/openapi/util/standard-responses.ts index 0b6534a6b7..0e4d53a32d 100644 --- a/src/lib/openapi/util/standard-responses.ts +++ b/src/lib/openapi/util/standard-responses.ts @@ -25,12 +25,23 @@ const conflictResponse = { 'The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.', } as const; +const contentTooLargeResponse = { + description: + 'The body request body is larger than what we accept. By default we only accept bodies of 100kB or less', +} as const; + +const unsupportedMediaTypeResponse = { + description: `The operation does not support request payloads of the provided type. Please ensure that you're using one of the listed payload types and that you have specified the right content type in the "content-type" header.`, +} as const; + const standardResponses = { 400: badRequestResponse, 401: unauthorizedResponse, 403: forbiddenResponse, 404: notFoundResponse, 409: conflictResponse, + 413: contentTooLargeResponse, + 415: unsupportedMediaTypeResponse, } as const; type StandardResponses = typeof standardResponses; diff --git a/src/lib/routes/edge-api/index.ts b/src/lib/routes/edge-api/index.ts index 0867c8e021..4dafd86c9b 100644 --- a/src/lib/routes/edge-api/index.ts +++ b/src/lib/routes/edge-api/index.ts @@ -7,16 +7,20 @@ import { createResponseSchema } from '../../openapi/util/create-response-schema' import { IAuthRequest, RequestBody } from '../unleash-types'; import { createRequestSchema } from '../../openapi/util/create-request-schema'; import { - validateEdgeTokensSchema, - ValidateEdgeTokensSchema, -} from '../../openapi/spec/validate-edge-tokens-schema'; + validatedEdgeTokensSchema, + ValidatedEdgeTokensSchema, +} from '../../openapi/spec/validated-edge-tokens-schema'; import ClientInstanceService from '../../services/client-metrics/instance-service'; import EdgeService from '../../services/edge-service'; import { OpenApiService } from '../../services/openapi-service'; -import { emptyResponse } from '../../openapi/util/standard-responses'; +import { + emptyResponse, + getStandardResponses, +} from '../../openapi/util/standard-responses'; import { BulkMetricsSchema } from '../../openapi/spec/bulk-metrics-schema'; import ClientMetricsServiceV2 from '../../services/client-metrics/metrics-service-v2'; import { clientMetricsEnvBulkSchema } from '../../services/client-metrics/schema'; +import { TokenStringListSchema } from '../../openapi'; export default class EdgeController extends Controller { private readonly logger: Logger; @@ -59,12 +63,14 @@ export default class EdgeController extends Controller { middleware: [ this.openApiService.validPath({ tags: ['Edge'], + summary: 'Check which tokens are valid', + description: + 'This operation accepts a list of tokens to validate. Unleash will validate each token you provide. For each valid token you provide, Unleash will return the token along with its type and which projects it has access to.', operationId: 'getValidTokens', - requestBody: createRequestSchema( - 'validateEdgeTokensSchema', - ), + requestBody: createRequestSchema('tokenStringListSchema'), responses: { - 200: createResponseSchema('validateEdgeTokensSchema'), + 200: createResponseSchema('validatedEdgeTokensSchema'), + ...getStandardResponses(400, 413, 415), }, }), ], @@ -78,10 +84,13 @@ export default class EdgeController extends Controller { middleware: [ this.openApiService.validPath({ tags: ['Edge'], + summary: 'Send metrics from Edge', + description: `This operation accepts batched metrics from Edge. Metrics will be inserted into Unleash's metrics storage`, operationId: 'bulkMetrics', requestBody: createRequestSchema('bulkMetricsSchema'), responses: { 202: emptyResponse, + ...getStandardResponses(400, 413, 415), }, }), ], @@ -89,16 +98,14 @@ export default class EdgeController extends Controller { } async getValidTokens( - req: RequestBody, - res: Response, + req: RequestBody, + res: Response, ): Promise { - const tokens = await this.edgeService.getValidTokens( - req.body.tokens as string[], - ); - this.openApiService.respondWithValidation( + const tokens = await this.edgeService.getValidTokens(req.body.tokens); + this.openApiService.respondWithValidation( 200, res, - validateEdgeTokensSchema.$id, + validatedEdgeTokensSchema.$id, tokens, ); } diff --git a/src/lib/services/edge-service.ts b/src/lib/services/edge-service.ts index 8206fbb4ee..ba0f354f4b 100644 --- a/src/lib/services/edge-service.ts +++ b/src/lib/services/edge-service.ts @@ -3,7 +3,7 @@ import { Logger } from '../logger'; import { IApiTokenStore } from '../types/stores/api-token-store'; import { EdgeTokenSchema } from '../openapi/spec/edge-token-schema'; import { constantTimeCompare } from '../util/constantTimeCompare'; -import { ValidateEdgeTokensSchema } from '../openapi/spec/validate-edge-tokens-schema'; +import { ValidatedEdgeTokensSchema } from '../openapi/spec/validated-edge-tokens-schema'; export default class EdgeService { private logger: Logger; @@ -18,7 +18,7 @@ export default class EdgeService { this.apiTokenStore = apiTokenStore; } - async getValidTokens(tokens: string[]): Promise { + async getValidTokens(tokens: string[]): Promise { const activeTokens = await this.apiTokenStore.getAllActive(); const edgeTokens = tokens.reduce((result: EdgeTokenSchema[], token) => { const dbToken = activeTokens.find((activeToken) => diff --git a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap index 33d2c6cd10..ab7b385e92 100644 --- a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap +++ b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap @@ -361,6 +361,7 @@ exports[`should serve the OpenAPI spec 1`] = ` "type": "object", }, "bulkMetricsSchema": { + "description": "A batch of metrics accumulated by Edge (or other compatible applications). Includes both application registrations as well usage metrics from clients", "properties": { "applications": { "items": { @@ -375,14 +376,29 @@ exports[`should serve the OpenAPI spec 1`] = ` "type": "array", }, }, + "required": [ + "applications", + "metrics", + ], "type": "object", }, "bulkRegistrationSchema": { + "description": "An application registration. Defines the format POSTed by our server-side SDKs when they're starting up", "properties": { "appName": { + "description": "The name of the application that is evaluating toggles", + "example": "Ingress load balancer", "type": "string", }, "connectVia": { + "description": "A list of applications this app registration has been registered through. If connected directly to Unleash, this is an empty list. + This can be used in later visualizations to tell how many levels of proxy or Edge instances our SDKs have connected through", + "example": [ + { + "appName": "unleash-edge", + "instanceId": "edge-pod-bghzv5", + }, + ], "items": { "properties": { "appName": { @@ -401,21 +417,36 @@ exports[`should serve the OpenAPI spec 1`] = ` "type": "array", }, "environment": { + "description": "Which environment the application is running in", + "example": "development", "type": "string", }, "instanceId": { + "description": "A [(somewhat) unique identifier](https://docs.getunleash.io/reference/sdks/node#advanced-usage) for the application", + "example": "application-name-dacb1234", "type": "string", }, "interval": { + "description": "How often (in seconds) the application refreshes its features", + "example": 10, "type": "number", }, "sdkVersion": { + "description": "The version the sdk is running. Typically :", + "example": "unleash-client-java:8.0.0", "type": "string", }, "started": { "$ref": "#/components/schemas/dateSchema", + "description": "The application started at", + "example": "1952-03-11T12:00:00.000Z", }, "strategies": { + "description": "Enabled [strategies](https://docs.getunleash.io/reference/activation-strategies) in the application", + "example": [ + "standard", + "gradualRollout", + ], "items": { "type": "string", }, @@ -425,6 +456,7 @@ exports[`should serve the OpenAPI spec 1`] = ` "required": [ "appName", "instanceId", + "environment", ], "type": "object", }, @@ -604,36 +636,56 @@ exports[`should serve the OpenAPI spec 1`] = ` }, "clientMetricsEnvSchema": { "additionalProperties": true, + "description": "Used for reporting feature evaluation results from SDKs", "properties": { "appName": { + "description": "The name of the application the SDK is being used in", + "example": "accounting", "type": "string", }, "environment": { + "description": "Which environment the SDK is being used in", + "example": "development", "type": "string", }, "featureName": { + "description": "Name of the feature checked by the SDK", + "example": "my.special.feature", "type": "string", }, "no": { + "description": "How many times the toggle evaluated to false", + "example": 50, "type": "number", }, "timestamp": { "$ref": "#/components/schemas/dateSchema", + "description": "The start of the time window these metrics are valid for. The window is 1 hour wide", + "example": "1926-05-08T12:00:00.000Z", }, "variants": { "additionalProperties": { "minimum": 0, "type": "integer", }, + "description": "How many times each variant was returned", + "example": { + "variantA": 15, + "variantB": 25, + "variantC": 5, + }, "type": "object", }, "yes": { + "description": "How many times the toggle evaluated to true", + "example": 974, "type": "number", }, }, "required": [ "featureName", "appName", + "environment", ], "type": "object", }, @@ -974,22 +1026,32 @@ exports[`should serve the OpenAPI spec 1`] = ` }, "edgeTokenSchema": { "additionalProperties": false, + "description": "A representation of a client token, limiting access to [CLIENT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#client-tokens) (used by serverside SDKs) or [FRONTEND](https://docs.getunleash.io/reference/api-tokens-and-client-keys#front-end-tokens) (used by proxy SDKs)", "properties": { "projects": { + "description": "The list of projects this token has access to. If the token has access to specific projects they will be listed here. If the token has access to all projects it will be represented as [\`*\`]", + "example": [ + "developerexperience", + "enterprisegrowth", + ], "items": { "type": "string", }, "type": "array", }, "token": { + "description": "The actual token value. [Unleash API tokens](https://docs.getunleash.io/reference/api-tokens-and-client-keys) are comprised of three parts. :.randomcharacters", + "example": "*:development.5c806b5320c88cf27e81f3e9b97dab298a77d5879316e3c2d806206b", "type": "string", }, "type": { + "description": "The [API token](https://docs.getunleash.io/reference/api-tokens-and-client-keys#api-tokens)'s **type**. Unleash supports three different types of API tokens ([ADMIN](https://docs.getunleash.io/reference/api-tokens-and-client-keys#admin-tokens), [CLIENT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#client-tokens), [FRONTEND](https://docs.getunleash.io/reference/api-tokens-and-client-keys#front-end-tokens)). They all have varying access, so when validating a token it's important to know what kind you're dealing with", "enum": [ "client", "admin", "frontend", ], + "example": "client", "type": "string", }, }, @@ -3852,6 +3914,27 @@ Stats are divided into current and previous **windows**. ], "type": "object", }, + "tokenStringListSchema": { + "additionalProperties": true, + "description": "A list of unleash tokens to validate against known tokens", + "properties": { + "tokens": { + "description": "Tokens that we want to get access information about", + "example": [ + "aproject:development.randomstring", + "[]:production.randomstring", + ], + "items": { + "type": "string", + }, + "type": "array", + }, + }, + "required": [ + "tokens", + ], + "type": "object", + }, "tokenUserSchema": { "additionalProperties": false, "properties": { @@ -4300,28 +4383,6 @@ Stats are divided into current and previous **windows**. }, "type": "array", }, - "validateEdgeTokensSchema": { - "additionalProperties": false, - "properties": { - "tokens": { - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/edgeTokenSchema", - }, - { - "type": "string", - }, - ], - }, - "type": "array", - }, - }, - "required": [ - "tokens", - ], - "type": "object", - }, "validatePasswordSchema": { "additionalProperties": false, "properties": { @@ -4349,6 +4410,23 @@ Stats are divided into current and previous **windows**. ], "type": "object", }, + "validatedEdgeTokensSchema": { + "additionalProperties": false, + "description": "A object containing a list of valid Unleash tokens.", + "properties": { + "tokens": { + "description": "The list of Unleash token objects. Each object contains the token itself and some additional metadata.", + "items": { + "$ref": "#/components/schemas/edgeTokenSchema", + }, + "type": "array", + }, + }, + "required": [ + "tokens", + ], + "type": "object", + }, "variantSchema": { "additionalProperties": false, "properties": { @@ -9257,6 +9335,7 @@ If the provided project does not exist, the list of events will be empty.", }, "/edge/metrics": { "post": { + "description": "This operation accepts batched metrics from Edge. Metrics will be inserted into Unleash's metrics storage", "operationId": "bulkMetrics", "requestBody": { "content": { @@ -9273,7 +9352,17 @@ If the provided project does not exist, the list of events will be empty.", "202": { "description": "This response has no body.", }, + "400": { + "description": "The request data does not match what we expect.", + }, + "413": { + "description": "The body request body is larger than what we accept. By default we only accept bodies of 100kB or less", + }, + "415": { + "description": "The operation does not support request payloads of the provided type. Please ensure that you're using one of the listed payload types and that you have specified the right content type in the "content-type" header.", + }, }, + "summary": "Send metrics from Edge", "tags": [ "Edge", ], @@ -9281,16 +9370,17 @@ If the provided project does not exist, the list of events will be empty.", }, "/edge/validate": { "post": { + "description": "This operation accepts a list of tokens to validate. Unleash will validate each token you provide. For each valid token you provide, Unleash will return the token along with its type and which projects it has access to.", "operationId": "getValidTokens", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/validateEdgeTokensSchema", + "$ref": "#/components/schemas/tokenStringListSchema", }, }, }, - "description": "validateEdgeTokensSchema", + "description": "tokenStringListSchema", "required": true, }, "responses": { @@ -9298,13 +9388,23 @@ If the provided project does not exist, the list of events will be empty.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/validateEdgeTokensSchema", + "$ref": "#/components/schemas/validatedEdgeTokensSchema", }, }, }, - "description": "validateEdgeTokensSchema", + "description": "validatedEdgeTokensSchema", + }, + "400": { + "description": "The request data does not match what we expect.", + }, + "413": { + "description": "The body request body is larger than what we accept. By default we only accept bodies of 100kB or less", + }, + "415": { + "description": "The operation does not support request payloads of the provided type. Please ensure that you're using one of the listed payload types and that you have specified the right content type in the "content-type" header.", }, }, + "summary": "Check which tokens are valid", "tags": [ "Edge", ],