Skip to content

Move Scaffolder API to OpenAPI#27771

Merged
benjdlambert merged 44 commits intobackstage:masterfrom
solimant:23819_scaffolder_openapi
Jul 29, 2025
Merged

Move Scaffolder API to OpenAPI#27771
benjdlambert merged 44 commits intobackstage:masterfrom
solimant:23819_scaffolder_openapi

Conversation

@solimant
Copy link
Copy Markdown
Contributor

@solimant solimant commented Nov 21, 2024

Hey, I just made a Pull Request!

Closes #23819

Server and client generated using:

yarn backstage-repo-tools package schema openapi generate --server --client-package plugins/scaffolder-common

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)
  • All your commits have a Signed-off-by line in the message. (more info)

@solimant solimant requested review from a team as code owners November 21, 2024 16:51
@github-actions github-actions Bot added area:catalog Related to the Catalog Project Area area:scaffolder Everything and all things related to the scaffolder project area labels Nov 21, 2024
@backstage-goalie
Copy link
Copy Markdown
Contributor

backstage-goalie Bot commented Nov 21, 2024

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@backstage/backend-openapi-utils packages/backend-openapi-utils minor v0.5.5
@backstage/repo-tools packages/repo-tools patch v0.15.0
@backstage/plugin-scaffolder-backend plugins/scaffolder-backend minor v2.1.0
@backstage/plugin-scaffolder-common plugins/scaffolder-common minor v1.6.0
@backstage/plugin-scaffolder-node plugins/scaffolder-node minor v0.10.0
@backstage/plugin-scaffolder-react plugins/scaffolder-react minor v1.18.1-next.0
@backstage/plugin-scaffolder plugins/scaffolder minor v1.33.1-next.0

@backstage-goalie
Copy link
Copy Markdown
Contributor

Thanks for the contribution!
All commits need to be DCO signed before they are reviewed. Please refer to the the DCO section in CONTRIBUTING.md or the DCO status for more info.

@solimant solimant force-pushed the 23819_scaffolder_openapi branch from a04277c to 0cd8958 Compare November 21, 2024 17:12
Copy link
Copy Markdown
Member

@Rugvip Rugvip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for looking at this! 👍

Is the goal to wire up the router etc with this as well in this PR? I'd really be needed to ensure that the schema is correct and remains so.

type: object
properties:
entity:
$ref: '../../../catalog-backend/src/schema/openapi.yaml#/components/schemas/UserEntity'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I think it's best to keep this one opaque. As an adopter of Backstage you can extend the UserEntity schema anyway, so there's kinda no point aiming to model this imo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I'll adjust here, and remove the addition from the Catalog OpenAPI schema.

Copy link
Copy Markdown
Contributor Author

@solimant solimant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the goal to wire up the router etc with this as well in this PR? I'd really be needed to ensure that the schema is correct and remains so.

@Rugvip - Yes, that's the goal, and I'm working on making more commits for that. And, yes, the schema needs to be correct 100%. That's the reason why I started with that since everything else is pretty much a matter of code generation.

type: object
properties:
entity:
$ref: '../../../catalog-backend/src/schema/openapi.yaml#/components/schemas/UserEntity'
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I'll adjust here, and remove the addition from the Catalog OpenAPI schema.

@solimant solimant force-pushed the 23819_scaffolder_openapi branch from 0cd8958 to 93cc245 Compare December 2, 2024 16:18
@github-actions github-actions Bot removed the area:catalog Related to the Catalog Project Area label Dec 2, 2024
@solimant
Copy link
Copy Markdown
Contributor Author

solimant commented Dec 6, 2024

@aramissennyeydd - I'm cleaning up a few things, and I noticed that we've got some schemas defined in OpenAPI and the corresponding generated TypeScript type, and also defined separately (manually) in other places. For example, Entity defined in packages/catalog-model/src/entity/Entity.ts and in plugins/catalog-backend/src/schema/openapi/generated/models/Entity.model.ts. Is that intentional?

@solimant
Copy link
Copy Markdown
Contributor Author

solimant commented Dec 6, 2024

@benjdlambert - On a separate note, I'm seeing an issue with properties that have special characters, such as backstage:permissions and EXPERIMENTAL_recovery, where the generated TypeScript type is omitting those special characters, which seems related to OpenAPITools/openapi-generator/issues/15261. How do we feel about manually adjusting those properties to match?

@solimant
Copy link
Copy Markdown
Contributor Author

solimant commented Dec 6, 2024

@Rugvip - because I've come across a few Scaffolder types that use JsonObject and similar types from @backstage/types (e.g. TaskStep), how do you feel about defining the types in @backstage/types in OpenAPI spec, and then repurpose *.ts files under `packages/types/src to export the generated TypeScript types? The benefit here is that we can cross-reference those common types in other OpenAPI spec YAMLs across the application.

CC: @benjdlambert, @aramissennyeydd

@aramissennyeydd
Copy link
Copy Markdown
Contributor

@solimant

For example, Entity defined in packages/catalog-model/src/entity/Entity.ts and in plugins/catalog-backend/src/schema/openapi/generated/models/Entity.model.ts. Is that intentional?

Yup this is intentional, the duplication here is minimal and the OpenAPI version should be looser than the catalog one.

@Rugvip - because I've come across a few Scaffolder types that use JsonObject and similar types from @backstage/types (e.g. TaskStep), how do you feel about defining the types in @backstage/types in OpenAPI spec, and then repurpose *.ts files under `packages/types/src to export the generated TypeScript types? The benefit here is that we can cross-reference those common types in other OpenAPI spec YAMLs across the application.

Similarly here, I don't think we gain much if we deduplicate the types and could start running into issues where we expect x version of the shared types and get y.

@benjdlambert - On a separate note, I'm seeing an issue with properties that have special characters, such as backstage:permissions and EXPERIMENTAL_recovery, where the generated TypeScript type is omitting those special characters, which seems related to OpenAPITools/openapi-generator#15261. How do we feel about manually adjusting those properties to match?

I can take a look into a fix here - in the meantime, can you just add these as an additionalProperties: {type: string} to allow them on requests and responses. That will give us an initial bit of schema definition and we can add them back once this is fixed.

description: Step that is part of a Template Entity.
TemplateEntityV1beta3:
allOf:
- $ref: '../../../catalog-backend/src/schema/openapi.yaml#/components/schemas/Entity'
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the response, @aramissennyeydd. Would like to get your feedback on this as well. Do we wanna cross-reference types from other OpenAPI specs like this one? For this one, the TypeScript type I'm matching is defined here, and is used in the Scaffolder router here.

Copy link
Copy Markdown
Contributor

@aramissennyeydd aramissennyeydd Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope - just copy this over from the other spec. I haven't figured out the stitching between specs yet. This kind of route may fail if you were you install this package on your local instance.

@solimant
Copy link
Copy Markdown
Contributor Author

solimant commented Dec 11, 2024

@aramissennyeydd - for the Scaffolder client, I'm thinking to do the following:

  1. Create plugins/scaffolder-common/src/ScaffolderClient.ts where we export class ScaffolderClient implements ScaffolderApi {...}
  2. Generate the client code under plugins/scaffolder-common/client/

What do you think? Or should we create a new package called packages/scaffolder-client similar to packages/catalog-client in structure?

@solimant
Copy link
Copy Markdown
Contributor Author

I should've clarified the part about ScaffolderClient. What I meant is to relocate plugins/scaffolder/src/api.ts to plugins/scaffolder-common/src/ScaffolderClient.ts, and also plugins/scaffolder-react/src/api/types.ts to plugins/scaffolder-common/src/api.ts.

@aramissennyeydd
Copy link
Copy Markdown
Contributor

@solimant The ScaffolderClient idea makes sense, we should just use whatever folder the yarn backstage-repo-tools package schema openapi generate --client <folder> outputs to (I believe /client).

scaffolder-common also makes sense, and we can re-export from scaffolder-react so it isn't breaking. For the CatalogClient, I kept the same API interface for the handwritten client, but changed out the internals to use the generated client - we can probably do the same here. Also helps to ensure the types match up fully.

@github-actions
Copy link
Copy Markdown
Contributor

This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution!

@github-actions github-actions Bot added the stale label Dec 26, 2024
@solimant
Copy link
Copy Markdown
Contributor Author

Please remove the "stale" label.

@awanlin
Copy link
Copy Markdown
Collaborator

awanlin commented Dec 26, 2024

Hi @solimant, the best way to avoid this going stale while you wait for reviews is to rebase. Your branch is currently 690 commits behind.

@github-actions github-actions Bot removed the stale label Dec 26, 2024
solimant added 21 commits July 28, 2025 20:59
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Signed-off-by: solimant <solimant@users.noreply.github.com>
Copy link
Copy Markdown
Member

@benjdlambert benjdlambert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor bits and then we can ship I think.

@@ -0,0 +1,10 @@
---
'@backstage/backend-openapi-utils': minor
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'@backstage/backend-openapi-utils': minor

This should probably be in another changeset, and also only a patch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also a changeset needed for repo-tool as well?

| 'failed'
| 'open'
| 'processing';
| 'processing'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, think these types might need a cleanup, but happy to take that before the mainline release if that's OK? Going to try and ship this ASAP.

if (taskId) {
analytics.captureEvent('retried', 'Template has been retried');
await scaffolderApi.retry?.(taskId);
await scaffolderApi.retry?.({ taskId });
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is a breaking change to the client which we can't make yet, this needs updating in our wrapping client to take just taskId.

There's a bigger piece of work which is to make sure that all the functions of the scaffolder API follow this pattern ({ taskId }) for example, but rather make that change as a bigger breaking change instead.

Signed-off-by: benjdlambert <ben@blam.sh>
Signed-off-by: benjdlambert <ben@blam.sh>
Signed-off-by: benjdlambert <ben@blam.sh>
@benjdlambert
Copy link
Copy Markdown
Member

benjdlambert commented Jul 29, 2025

@solimant I created a separate changeset for the -react package with some additional callouts to all the deprecations.

I think that covers everything for now, but if you're willing to cleanup the types in a followup PR those deprecations will need to also be called out explicitly in another changeset too 🙏

Approving and auto-merge on! Thanks a lot for the effort here all round from everyone involved 🎉 @aramissennyeydd too 👍

Signed-off-by: benjdlambert <ben@blam.sh>
@github-actions
Copy link
Copy Markdown
Contributor

Thank you for contributing to Backstage! The changes in this pull request will be part of the 1.42.0 release, scheduled for Tue, 19 Aug 2025.

@benjdlambert benjdlambert mentioned this pull request Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:scaffolder Everything and all things related to the scaffolder project area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: Backend client for Scaffolder

7 participants