From 37ce81a7272dec540893fcc8db4b5369bde70c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Fri, 3 Mar 2023 16:36:23 +0100 Subject: [PATCH] chore: re-use the same client schema for proxy (#3251) ## About the changes client-metrics-schema is less strict than proxy-metrics-schema because the former allows empty `instanceId` and also supports dates as timestamps as well as date-formatted strings. Using the same schema makes sense to reduce maintainability costs and it's less error-prone if we need to modify the schema because underlying the schema they both use the same code. The reasoning is that proxy metrics should align with our client metrics. Alternatively, we have new endpoints for edge metrics that will aggregate and bucket by client. ![image](https://user-images.githubusercontent.com/455064/222738911-4c443e02-3072-4042-bfde-327da8dd46fe.png) ## Discussion points Will we ever want to evolve proxy-metrics differently than client-metrics? I'm under the assumption that the answer is no --- src/lib/openapi/index.ts | 2 - src/lib/openapi/spec/client-metrics-schema.ts | 30 ++------ src/lib/openapi/spec/index.ts | 1 - src/lib/openapi/spec/proxy-metrics-schema.ts | 55 -------------- src/lib/routes/proxy-api/index.ts | 6 +- src/lib/services/proxy-service.ts | 4 +- .../__snapshots__/openapi.e2e.test.ts.snap | 75 ------------------- 7 files changed, 12 insertions(+), 161 deletions(-) delete mode 100644 src/lib/openapi/spec/proxy-metrics-schema.ts diff --git a/src/lib/openapi/index.ts b/src/lib/openapi/index.ts index b7c0aa221a..b1dc56e14d 100644 --- a/src/lib/openapi/index.ts +++ b/src/lib/openapi/index.ts @@ -82,7 +82,6 @@ import { proxyClientSchema, proxyFeatureSchema, proxyFeaturesSchema, - proxyMetricsSchema, publicSignupTokenCreateSchema, projectStatsSchema, publicSignupTokenSchema, @@ -230,7 +229,6 @@ export const schemas = { proxyClientSchema, proxyFeatureSchema, proxyFeaturesSchema, - proxyMetricsSchema, publicSignupTokenCreateSchema, publicSignupTokenSchema, publicSignupTokensSchema, diff --git a/src/lib/openapi/spec/client-metrics-schema.ts b/src/lib/openapi/spec/client-metrics-schema.ts index 7d615b604e..c194c9a4d9 100644 --- a/src/lib/openapi/spec/client-metrics-schema.ts +++ b/src/lib/openapi/spec/client-metrics-schema.ts @@ -6,25 +6,15 @@ export const clientMetricsSchema = { type: 'object', required: ['appName', 'bucket'], properties: { - appName: { - type: 'string', - }, - instanceId: { - type: 'string', - }, - environment: { - type: 'string', - }, + appName: { type: 'string' }, + instanceId: { type: 'string' }, + environment: { type: 'string' }, bucket: { type: 'object', required: ['start', 'stop', 'toggles'], properties: { - start: { - $ref: '#/components/schemas/dateSchema', - }, - stop: { - $ref: '#/components/schemas/dateSchema', - }, + start: { $ref: '#/components/schemas/dateSchema' }, + stop: { $ref: '#/components/schemas/dateSchema' }, toggles: { type: 'object', example: { @@ -45,14 +35,8 @@ export const clientMetricsSchema = { additionalProperties: { type: 'object', properties: { - yes: { - type: 'integer', - minimum: 0, - }, - no: { - type: 'integer', - minimum: 0, - }, + yes: { type: 'integer', minimum: 0 }, + no: { type: 'integer', minimum: 0 }, variants: { type: 'object', additionalProperties: { diff --git a/src/lib/openapi/spec/index.ts b/src/lib/openapi/spec/index.ts index d08c8da12f..0677a1e2a1 100644 --- a/src/lib/openapi/spec/index.ts +++ b/src/lib/openapi/spec/index.ts @@ -66,7 +66,6 @@ export * from './feature-types-schema'; export * from './feature-usage-schema'; export * from './health-report-schema'; export * from './proxy-feature-schema'; -export * from './proxy-metrics-schema'; export * from './search-events-schema'; export * from './set-ui-config-schema'; export * from './client-feature-schema'; diff --git a/src/lib/openapi/spec/proxy-metrics-schema.ts b/src/lib/openapi/spec/proxy-metrics-schema.ts deleted file mode 100644 index 3fd8007985..0000000000 --- a/src/lib/openapi/spec/proxy-metrics-schema.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { FromSchema } from 'json-schema-to-ts'; - -export const proxyMetricsSchema = { - $id: '#/components/schemas/proxyMetricsSchema', - type: 'object', - required: ['appName', 'instanceId', 'bucket'], - properties: { - appName: { type: 'string' }, - instanceId: { type: 'string' }, - environment: { type: 'string' }, - bucket: { - type: 'object', - required: ['start', 'stop', 'toggles'], - properties: { - start: { type: 'string', format: 'date-time' }, - stop: { type: 'string', format: 'date-time' }, - toggles: { - type: 'object', - example: { - myCoolToggle: { - yes: 25, - no: 42, - variants: { - blue: 6, - green: 15, - red: 46, - }, - }, - myOtherToggle: { - yes: 0, - no: 100, - }, - }, - additionalProperties: { - type: 'object', - properties: { - yes: { type: 'integer', minimum: 0 }, - no: { type: 'integer', minimum: 0 }, - variants: { - type: 'object', - additionalProperties: { - type: 'integer', - minimum: 0, - }, - }, - }, - }, - }, - }, - }, - }, - components: {}, -} as const; - -export type ProxyMetricsSchema = FromSchema; diff --git a/src/lib/routes/proxy-api/index.ts b/src/lib/routes/proxy-api/index.ts index c5fc532591..24e9383f1e 100644 --- a/src/lib/routes/proxy-api/index.ts +++ b/src/lib/routes/proxy-api/index.ts @@ -9,13 +9,13 @@ import { import { Logger } from '../../logger'; import ApiUser from '../../types/api-user'; import { + ClientMetricsSchema, createRequestSchema, createResponseSchema, emptyResponse, ProxyClientSchema, proxyFeaturesSchema, ProxyFeaturesSchema, - ProxyMetricsSchema, } from '../../openapi'; import { Context } from 'unleash-client'; import { enrichContextWithIp } from '../../proxy'; @@ -95,7 +95,7 @@ export default class ProxyController extends Controller { this.services.openApiService.validPath({ tags: ['Frontend API'], operationId: 'registerFrontendMetrics', - requestBody: createRequestSchema('proxyMetricsSchema'), + requestBody: createRequestSchema('clientMetricsSchema'), responses: { 200: emptyResponse }, }), ], @@ -168,7 +168,7 @@ export default class ProxyController extends Controller { } private async registerProxyMetrics( - req: ApiUserRequest, + req: ApiUserRequest, res: Response, ) { await this.services.proxyService.registerProxyMetrics( diff --git a/src/lib/services/proxy-service.ts b/src/lib/services/proxy-service.ts index b832990319..ad1314395b 100644 --- a/src/lib/services/proxy-service.ts +++ b/src/lib/services/proxy-service.ts @@ -1,6 +1,6 @@ import { IUnleashConfig, IUnleashServices, IUnleashStores } from '../types'; import { Logger } from '../logger'; -import { ProxyFeatureSchema, ProxyMetricsSchema } from '../openapi'; +import { ClientMetricsSchema, ProxyFeatureSchema } from '../openapi'; import ApiUser from '../types/api-user'; import { Context, @@ -94,7 +94,7 @@ export class ProxyService { async registerProxyMetrics( token: ApiUser, - metrics: ProxyMetricsSchema, + metrics: ClientMetricsSchema, ip: string, ): Promise { ProxyService.assertExpectedTokenType(token); 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 54fad762ac..70c5232ace 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 @@ -3027,81 +3027,6 @@ Stats are divided into current and previous **windows**. ], "type": "object", }, - "proxyMetricsSchema": { - "properties": { - "appName": { - "type": "string", - }, - "bucket": { - "properties": { - "start": { - "format": "date-time", - "type": "string", - }, - "stop": { - "format": "date-time", - "type": "string", - }, - "toggles": { - "additionalProperties": { - "properties": { - "no": { - "minimum": 0, - "type": "integer", - }, - "variants": { - "additionalProperties": { - "minimum": 0, - "type": "integer", - }, - "type": "object", - }, - "yes": { - "minimum": 0, - "type": "integer", - }, - }, - "type": "object", - }, - "example": { - "myCoolToggle": { - "no": 42, - "variants": { - "blue": 6, - "green": 15, - "red": 46, - }, - "yes": 25, - }, - "myOtherToggle": { - "no": 100, - "yes": 0, - }, - }, - "type": "object", - }, - }, - "required": [ - "start", - "stop", - "toggles", - ], - "type": "object", - }, - "environment": { - "type": "string", - }, - "instanceId": { - "type": "string", - }, - }, - "required": [ - "appName", - "instanceId", - "bucket", - ], - "type": "object", - }, "publicSignupTokenCreateSchema": { "additionalProperties": false, "properties": {