diff --git a/.changeset/honest-comics-ring.md b/.changeset/honest-comics-ring.md new file mode 100644 index 0000000000..38a962c5d3 --- /dev/null +++ b/.changeset/honest-comics-ring.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-todo-backend': patch +--- + +Added OpenAPI schema diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index d98a44f874..9385ec0ee6 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -45,6 +45,7 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-openapi-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", diff --git a/plugins/todo-backend/src/schema/openapi.generated.ts b/plugins/todo-backend/src/schema/openapi.generated.ts new file mode 100644 index 0000000000..54486a5615 --- /dev/null +++ b/plugins/todo-backend/src/schema/openapi.generated.ts @@ -0,0 +1,208 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export default { + openapi: '3.0.3', + info: { + title: '@backstage/plugin-todo-backend', + version: '1', + description: + 'The Backstage backend plugin that provides source code todo comment browsing.', + license: { + name: 'Apache-2.0', + url: 'http://www.apache.org/licenses/LICENSE-2.0.html', + }, + contact: {}, + }, + servers: [ + { + url: '/', + }, + ], + components: { + examples: {}, + headers: {}, + parameters: {}, + requestBodies: {}, + responses: {}, + schemas: { + TodoItem: { + type: 'object', + properties: { + text: { + type: 'string', + description: 'The contents of the TODO comment', + }, + tag: { + type: 'string', + description: 'The tag used, e.g. TODO, FIXME', + }, + author: { + type: 'string', + description: 'References author, if any', + }, + viewUrl: { + type: 'string', + description: 'URL used to view the file', + }, + lineNumber: { + type: 'integer', + description: 'The line number of the file that the TODO occurs at', + }, + repoFilePath: { + type: 'string', + description: + 'The path of the file containing the TODO within the repo', + }, + }, + required: ['text', 'tag'], + additionalProperties: false, + }, + }, + securitySchemes: { + JWT: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + paths: { + '/v1/todos': { + get: { + operationId: 'ListTodos', + responses: { + '200': { + description: 'Ok', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/TodoItem', + }, + }, + totalCount: { + type: 'integer', + }, + offset: { + type: 'integer', + }, + limit: { + type: 'integer', + }, + }, + required: ['items', 'totalCount', 'offset', 'limit'], + additionalProperties: false, + }, + }, + }, + }, + '400': { + description: 'Bad request', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + error: { + type: 'object', + properties: { + message: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + security: [ + {}, + { + JWT: [], + }, + ], + parameters: [ + { + name: 'entity', + in: 'query', + required: true, + schema: { + type: 'string', + minLength: 1, + description: 'A reference to the entity to list TODO items for', + }, + }, + { + name: 'orderBy', + in: 'query', + required: false, + schema: { + type: 'string', + pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$', + description: + 'The field and direction used to sort the listed TODO items', + }, + }, + { + name: 'filter', + in: 'query', + required: false, + schema: { + type: 'array', + description: + 'A list of filters used to narrow down the listed TODO items', + items: { + type: 'string', + pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$', + }, + }, + }, + { + name: 'offset', + in: 'query', + required: false, + schema: { + type: 'integer', + minimum: 0, + description: 'The offset at which to start listing TODO items', + }, + }, + { + name: 'limit', + in: 'query', + required: false, + schema: { + type: 'integer', + minimum: 1, + description: 'The number of TODO items to list', + }, + }, + ], + }, + }, + }, +} as const; diff --git a/plugins/todo-backend/src/schema/openapi.yaml b/plugins/todo-backend/src/schema/openapi.yaml new file mode 100644 index 0000000000..3fba129644 --- /dev/null +++ b/plugins/todo-backend/src/schema/openapi.yaml @@ -0,0 +1,132 @@ +openapi: 3.0.3 + +info: + title: '@backstage/plugin-todo-backend' + version: '1' + description: The Backstage backend plugin that provides source code todo comment browsing. + license: + name: Apache-2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + contact: {} + +servers: + - url: / + +components: + examples: {} + headers: {} + parameters: {} + requestBodies: {} + responses: {} + schemas: + TodoItem: + type: object + properties: + text: + type: string + description: The contents of the TODO comment + tag: + type: string + description: The tag used, e.g. TODO, FIXME + author: + type: string + description: References author, if any + viewUrl: + type: string + description: URL used to view the file + lineNumber: + type: integer + description: The line number of the file that the TODO occurs at + repoFilePath: + type: string + description: The path of the file containing the TODO within the repo + required: + - text + - tag + additionalProperties: false + securitySchemes: + JWT: + type: http + scheme: bearer + bearerFormat: JWT +paths: + /v1/todos: + get: + operationId: ListTodos + responses: + '200': + description: Ok + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/TodoItem' + totalCount: + type: integer + offset: + type: integer + limit: + type: integer + required: + - items + - totalCount + - offset + - limit + additionalProperties: false + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + message: + type: string + security: + - {} + - JWT: [] + parameters: + - name: entity + in: query + required: true + schema: + type: string + minLength: 1 + description: A reference to the entity to list TODO items for + - name: orderBy + in: query + required: false + schema: + type: string + pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$' + description: The field and direction used to sort the listed TODO items + - name: filter + in: query + required: false + schema: + type: array + description: A list of filters used to narrow down the listed TODO items + items: + type: string + pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$' + - name: offset + in: query + required: false + schema: + type: integer + minimum: 0 + description: The offset at which to start listing TODO items + - name: limit + in: query + required: false + schema: + type: integer + minimum: 1 + description: The number of TODO items to list diff --git a/plugins/todo-backend/src/service/router.ts b/plugins/todo-backend/src/service/router.ts index 5954fab009..364cbef6b0 100644 --- a/plugins/todo-backend/src/service/router.ts +++ b/plugins/todo-backend/src/service/router.ts @@ -25,6 +25,8 @@ import { parseIntegerParam, parseOrderByParam, } from '../lib/utils'; +import spec from '../schema/openapi.generated'; +import type { ApiRouter } from '@backstage/backend-openapi-utils'; /** @public */ export interface RouterOptions { @@ -37,7 +39,7 @@ export async function createRouter( ): Promise { const { todoService } = options; - const router = Router(); + const router = Router() as ApiRouter; router.use(express.json()); router.get('/v1/todos', async (req, res) => { diff --git a/yarn.lock b/yarn.lock index c6a18d61a5..10b595c716 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9564,6 +9564,7 @@ __metadata: resolution: "@backstage/plugin-todo-backend@workspace:plugins/todo-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^"