Skip to content

Use Semi-Automatic OpenAPI Specs of the Backend API#3300

Merged
tom2drum merged 2 commits intomainfrom
tom2drum/issue-3204
Feb 26, 2026
Merged

Use Semi-Automatic OpenAPI Specs of the Backend API#3300
tom2drum merged 2 commits intomainfrom
tom2drum/issue-3204

Conversation

@tom2drum
Copy link
Copy Markdown
Collaborator

Description and Related Issue(s)

Resolves #3204

Starting with backend v9, semi-automatic OpenAPI specs are generated per release and chain type and stored in the blockscout/swaggers repo. This PR updates the frontend to use those specs instead of a single static Swagger URL.

The REST API docs page now derives the core API spec URL from the backend: it fetches api/v2/config/backend-version (for the release number) and api/v2/config/backend (for openapi_spec_folder_name), then builds the URL as https://raw.githubusercontent.com/blockscout/swaggers/master/blockscout/{release}/{folder}/swagger.yaml. This ensures the displayed spec matches the running backend, including non-release builds (e.g. v9.3.2+commit.a7ab3460).

Proposed Changes

  • API docs (REST): RestApi fetches backend config and backend version, shows a loader while loading, then builds the core API Swagger URL from the response (release number + openapi_spec_folder_name). Other API sections (stats, bens, etc.) are unchanged.
  • API client: Added config_backend_version and use existing config_backend; extended types with BackendVersionConfig and BackendConfig (including openapi_spec_folder_name).
  • Config/features: Removed NEXT_PUBLIC_API_SPEC_URL from app config and from the envs validator schema; added it to preset-sync ignore list and to DEPRECATED_ENVS.md. Removed the variable from all env presets and from docs/ENVS.md.

Environment variable changes

  • Removed NEXT_PUBLIC_API_SPEC_URL — The REST API spec URL is now built automatically from the backend version and openapi_spec_folder_name returned by api/v2/config/backend-version and api/v2/config/backend, so this variable is no longer used. It is documented in docs/DEPRECATED_ENVS.md (deprecated in an upcoming release).

Breaking or Incompatible Changes

  • Removed support for NEXT_PUBLIC_API_SPEC_URL. Deployments that set a custom spec URL will now always see the spec that matches their backend version from the swaggers repo. If the backend does not expose the new config endpoints or the expected fields, the core API section may not load (fallback to a hardcoded URL was removed).

Additional Information

  • Spec URL format: https://raw.githubusercontent.com/blockscout/swaggers/master/blockscout/{release_number}/{chain_type}/swagger.yaml (e.g. 9.3.2, ethereum).
  • Release number is parsed from backend_version (e.g. v9.3.2 or v9.3.2+commit.a7ab3460).

Checklist for PR author

  • I have tested these changes locally.
  • I added tests to cover any new functionality, following this guide
  • Whenever I fix a bug, I include a regression test to ensure that the bug does not reappear silently.
  • If I have added a feature or functionality that is not privacy-compliant (e.g., tracking, analytics, third-party services), I have disabled it for private mode.
  • If I have added, changed, renamed, or removed an environment variable
    • I updated the list of environment variables in the documentation
    • I made the necessary changes to the validator script according to the guide
    • I added "ENVs" label to this pull request

Made with Cursor

@tom2drum tom2drum added the ENVs label Feb 26, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Auto reviews are disabled on this repository. To trigger a review, include @coderabbitai review in the PR description. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
types/api/configs.ts (1)

1-4: Prefer readonly fields for API config payloads.

These values are response metadata and should not be mutable in consumer code.

♻️ Suggested refactor
 export interface BackendConfig {
-  chain_type: string;
-  openapi_spec_folder_name: string;
+  readonly chain_type: string;
+  readonly openapi_spec_folder_name: string;
 }
As per coding guidelines: "Use `readonly` properties for object types by default to prevent accidental mutation; omit `readonly` only when the property is genuinely mutable."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@types/api/configs.ts` around lines 1 - 4, Update the BackendConfig interface
so its response metadata fields are immutable: change the properties on
BackendConfig (chain_type and openapi_spec_folder_name) to readonly fields;
locate the BackendConfig declaration in types/api/configs.ts and convert each
property to readonly to prevent accidental mutation by consumers.
ui/apiDocs/RestApi.tsx (1)

19-26: Scope these queries to config.apis.general too.

This avoids unnecessary config_backend* requests when the general API section is unavailable.

♻️ Suggested refactor
       refetchOnMount: false,
-      enabled: config.features.apiDocs.isEnabled,
+      enabled: config.features.apiDocs.isEnabled && Boolean(config.apis.general),
@@
       refetchOnMount: false,
-      enabled: config.features.apiDocs.isEnabled,
+      enabled: config.features.apiDocs.isEnabled && Boolean(config.apis.general),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui/apiDocs/RestApi.tsx` around lines 19 - 26, The queries created with
useApiQuery (e.g., the configVersionQuery) are only gated by
config.features.apiDocs.isEnabled and should also check that the general API
section is available; update the queryOptions.enabled for the relevant
useApiQuery calls to require both config.features.apiDocs.isEnabled &&
config.apis.general (or the equivalent truthy check on config.apis.general) so
the requests are skipped when the general API is not present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ui/apiDocs/RestApi.tsx`:
- Around line 58-60: The code currently returns the hardcoded REST_API_SECTIONS
when coreApiSwaggerUrl is falsy, which reintroduces the static core spec URL;
update the logic in RestApi.tsx (the block referencing coreApiSwaggerUrl and
REST_API_SECTIONS) to avoid falling back to REST_API_SECTIONS — instead return
an empty array or a filtered list that excludes the core/static section so the
UI only uses resolved config URLs (or handle the missing URL upstream), ensuring
the component does not reintroduce the hardcoded core spec.

In `@ui/apiDocs/utils.ts`:
- Around line 41-43: The current substring replace of DEFAULT_SERVER_NEW can
leave stray ports; instead parse req.url into a URL object, set url.protocol =
config.apis.general.protocol, url.hostname = config.apis.general.host and then
if config.apis.general.port set url.port = config.apis.general.port else set
url.port = '' to remove any original port, and return that URL; apply the same
change to the similar block referenced at lines 49-53 so both places use URL
parsing and explicit protocol/hostname/port assignment rather than string
replacement.

---

Nitpick comments:
In `@types/api/configs.ts`:
- Around line 1-4: Update the BackendConfig interface so its response metadata
fields are immutable: change the properties on BackendConfig (chain_type and
openapi_spec_folder_name) to readonly fields; locate the BackendConfig
declaration in types/api/configs.ts and convert each property to readonly to
prevent accidental mutation by consumers.

In `@ui/apiDocs/RestApi.tsx`:
- Around line 19-26: The queries created with useApiQuery (e.g., the
configVersionQuery) are only gated by config.features.apiDocs.isEnabled and
should also check that the general API section is available; update the
queryOptions.enabled for the relevant useApiQuery calls to require both
config.features.apiDocs.isEnabled && config.apis.general (or the equivalent
truthy check on config.apis.general) so the requests are skipped when the
general API is not present.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67ce6ae and bd43957.

📒 Files selected for processing (45)
  • configs/app/features/apiDocs.ts
  • configs/envs/.env.arbitrum
  • configs/envs/.env.arbitrum_nova
  • configs/envs/.env.arbitrum_sepolia
  • configs/envs/.env.base
  • configs/envs/.env.blackfort_testnet
  • configs/envs/.env.celo
  • configs/envs/.env.celo_sepolia
  • configs/envs/.env.eth
  • configs/envs/.env.eth_sepolia
  • configs/envs/.env.filecoin
  • configs/envs/.env.garnet
  • configs/envs/.env.gnosis
  • configs/envs/.env.immutable
  • configs/envs/.env.main
  • configs/envs/.env.mega_eth
  • configs/envs/.env.mekong
  • configs/envs/.env.neon_devnet
  • configs/envs/.env.numine
  • configs/envs/.env.optimism
  • configs/envs/.env.optimism_sepolia
  • configs/envs/.env.polygon
  • configs/envs/.env.rari_testnet
  • configs/envs/.env.rootstock_testnet
  • configs/envs/.env.scroll_sepolia
  • configs/envs/.env.shibarium
  • configs/envs/.env.stability_testnet
  • configs/envs/.env.tac
  • configs/envs/.env.tac_spb
  • configs/envs/.env.zetachain
  • configs/envs/.env.zetachain_testnet
  • configs/envs/.env.zilliqa
  • configs/envs/.env.zkevm
  • configs/envs/.env.zksync
  • configs/envs/.env.zora
  • deploy/tools/envs-validator/schemas/features/apiDocs.ts
  • deploy/tools/envs-validator/test/.env.base
  • docs/DEPRECATED_ENVS.md
  • docs/ENVS.md
  • lib/api/services/general/misc.ts
  • tools/preset-sync/index.ts
  • types/api/configs.ts
  • ui/apiDocs/RestApi.tsx
  • ui/apiDocs/utils.ts
  • ui/snippets/footer/Footer.tsx
💤 Files with no reviewable changes (38)
  • configs/envs/.env.optimism
  • configs/envs/.env.eth_sepolia
  • configs/envs/.env.zilliqa
  • configs/envs/.env.eth
  • configs/envs/.env.arbitrum_nova
  • configs/envs/.env.zora
  • configs/envs/.env.gnosis
  • configs/envs/.env.rootstock_testnet
  • configs/envs/.env.zksync
  • configs/envs/.env.zetachain_testnet
  • configs/envs/.env.celo
  • configs/envs/.env.base
  • configs/envs/.env.neon_devnet
  • configs/app/features/apiDocs.ts
  • deploy/tools/envs-validator/test/.env.base
  • configs/envs/.env.scroll_sepolia
  • deploy/tools/envs-validator/schemas/features/apiDocs.ts
  • configs/envs/.env.optimism_sepolia
  • configs/envs/.env.arbitrum_sepolia
  • configs/envs/.env.zetachain
  • configs/envs/.env.garnet
  • configs/envs/.env.main
  • configs/envs/.env.tac
  • configs/envs/.env.shibarium
  • configs/envs/.env.polygon
  • configs/envs/.env.blackfort_testnet
  • configs/envs/.env.zkevm
  • configs/envs/.env.immutable
  • configs/envs/.env.celo_sepolia
  • configs/envs/.env.rari_testnet
  • configs/envs/.env.numine
  • docs/ENVS.md
  • configs/envs/.env.mega_eth
  • configs/envs/.env.mekong
  • configs/envs/.env.arbitrum
  • configs/envs/.env.stability_testnet
  • configs/envs/.env.filecoin
  • configs/envs/.env.tac_spb

@tom2drum tom2drum merged commit 2f79681 into main Feb 26, 2026
20 of 21 checks passed
@tom2drum tom2drum deleted the tom2drum/issue-3204 branch February 26, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use Semi-Automatic OpenAPI Specs of the Backend API

1 participant