Skip to content

feat(portal): show each merged API's own SDK sample when the platform files samples by spec - #448

Open
saeedjamshaid wants to merge 5 commits into
devfrom
saeedjamshaid/code-samples-by-spec
Open

saeedjamshaid wants to merge 5 commits into
devfrom
saeedjamshaid/code-samples-by-spec

Conversation

@saeedjamshaid

Copy link
Copy Markdown
Collaborator

The problem

When two merged specs declare the same method and path, such as GET /status on two services, the platform's code samples hold one sample for the pair, keyed by path and method. The portal cannot tell whose it is, so since #435 it leaves the SDK sample off such an operation and warns.

The platform is adding a grouping to its samples file. When the operations come from two or more spec files, code-samples/<language>.json gains specs: each spec's samples, keyed by its main file relative to src/spec/. paths stays as it is, so released CLIs are unaffected.

Tracked in apimatic-io issue 2298.

What changes

  • Samples filed by spec are placed by spec. When a samples file has specs, each spec takes the samples filed under its own file, and only those. The file is matched exactly: orders/openapi.yaml for src/spec/orders/openapi.yaml. An operation two specs declare then shows each spec's own call. A spec with nothing filed under it shows no SDK sample, rather than calls from paths that may be another API's.
  • A file without specs is read as before. Every spec takes paths, less the operations two specs declare. Every samples file the platform sends today is of this kind.
  • The shared-operation warning now depends on the samples file. It moves from before the server run to after it, and appears only for a file without specs.
  • Samples no operation takes are checked within each spec when they are filed by spec, and the warning names the spec.
  • code-samples.json changes shape. The CLI writes this file for the template, and it becomes { paths, specs }, with specs keyed by section slug. Each section reads its own entry, or paths. A test holds the CLI's and the template's declarations of the file to one shape, as it does for portal.config.json.
  • Tidy-ups:
    • the samples warnings live together in src/prompts/portal/code-samples.ts;
    • PortalSource.sharedEndpoints goes, since the placed samples work out the shared operations.

What it prints

Without specs, the warning reads as before but prints after the samples arrive:

▲  More than one API definition declares this operation, so the portal shows no SDK sample on it:
│    • 'GET /status': 'spec/alpha/alpha.json' and 'spec/beta/beta.json'

A sample filed under a spec that declares no such operation:

▲  No operation in 'spec/orders/openapi.yaml' takes the code samples for POST /refunds.

Testing

  • pnpm test with APIMATIC_E2E=1, as CI runs it: 2052 passing, ESLint clean.
  • Unit:
    • placing samples with and without specs, and refusing a malformed specs;
    • exact matching: ./orders/openapi.yaml, orders\openapi.yaml, Orders/openapi.yaml and the folder orders match nothing, and a spec in a nested folder matches;
    • both warnings, and the template reading its section's entry, including a section named constructor.
  • End to end:
    • A new build of the merged fixture with its samples filed by spec shows each API's own call on both GET /status pages.
    • That build fails when the template is made to ignore specs.
    • The existing build without specs still shows no SDK sample on either /status page.
  • Against production: a real portal generate of the two-spec fixture. Production files have no specs yet, so the result matches feat(portal): build a portal from the spec folders APIMATIC-META.json merges #435's:
    • the warning names GET /status with both specs;
    • neither status page carries an SDK sample;
    • the other two pages carry their own calls.

Not in this PR

  • Nothing changes for users until the platform sends specs. The backend change is tracked in apimatic-io issue 2298.
  • An operation the platform folds into an identical one from an earlier spec is filed under the earlier spec only, so the later spec's page shows no SDK sample. The fix is on the backend.
  • A merged folder holding another API format beside its OpenAPI document, such as a Postman collection that sorts first, gets its SDK built from that other file. The CLI should refuse such a folder (apimatic-io issue 2307).

🤖 Generated with Claude Code

saeedjamshaid and others added 4 commits October 22, 2026 17:29
The samples file from /portal-artifacts gains `specs` when the operations come from two or more
spec files: each spec's samples, keyed by its main file relative to `src/spec/`. A spec filed so
now takes its samples from its own group alone, and one with no group takes none. A file without
`specs` is placed as after #2297.

code-samples.json becomes `{ paths, specs }`, with `specs` keyed by slug, and a test holds the
CLI's and the template's declarations of it to one shape.

Refs apimatic/apimatic-io#2298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w the samples are filed

Whether an operation two specs declare shows an SDK sample now depends on the samples file, so
the warning about it moves from the source to the placed samples, and prints once the samples
arrive. It names the operations only when the samples are not filed by spec.

Samples that no operation takes are checked within each spec when the samples are filed by spec,
and the warning names that spec's file. Without the filing, the check and its message are as
before. Both warnings now live in src/prompts/portal/code-samples.ts.

Refs apimatic/apimatic-io#2298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second end-to-end build of the merged fixture gives each spec its own samples, as the platform
files them, with `paths` holding the orders call for the operation both specs declare. Each
status page shows its own API's call and not the other's. The two merged blocks now share their
page paths and sample helper.

Refs apimatic/apimatic-io#2298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es file at the template's

The CLI's `CodeSamplesFile` now points to the template's declaration instead of restating it, as
`PortalBuildPaths` does, and the placed samples' doc names the shared endpoints rather than
repeating why they get no sample.

Refs apimatic/apimatic-io#2298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re unplaced samples sit by path

`UnplacedSamples.where` is the spec file, or `spec/` for the samples not filed by spec, in place of
a null that needed a comment; that warning now names './spec', as other warnings name a folder. A
catalog filed by spec answers no unfiled samples itself, and `undeclared` de-duplicates by the key
it compares with.

Refs apimatic/apimatic-io#2298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@saeedjamshaid

Copy link
Copy Markdown
Collaborator Author

I checked this against apimatic/codegen-v2#718, which writes specs. The two agree on:

  • the shape;
  • when specs appears (two or more spec files);
  • the key: Commons records RelativeFilePath relative to spec/ with forward slashes and no ./, which is what file.relativeTo(specDirectory) produces.

One gap: a specs key that matches no spec is dropped without a warning.

PlacedCodeSamples looks up each spec by its own file, so it never reads a key that no spec asks for. The spec that key was meant for then shows no SDK sample, and nothing is printed. The test "names, of the samples filed under a spec, those it does not declare, and checks nothing else" pins this behaviour with gamma/openapi.json.

This can already happen in the apimatic/apimatic-io#2307 case. When a merged folder holds a Postman collection beside the OpenAPI document, Commons builds the SDK from the Postman file. The key then names the Postman file while the portal reads the OpenAPI one, so that API's pages lose every sample silently.

Suggestion: warn once for each specs key that matches no PortalSpec, naming the key, next to reportUnplacedSamples. For example:

▲  The code samples filed under 'orders/postman.json' match no API definition in 'spec/', so no page shows them.

@saeedjamshaid

Copy link
Copy Markdown
Collaborator Author

Keeping this as is, on purpose. A key that matches no spec has one cause: a merged folder that the platform builds from another file than the OpenAPI document the portal reads (apimatic-io issue 2307). There the whole API's SDK comes from the wrong file, so a warning about samples would name a symptom rather than the cause or the fix. 2307 refuses such a folder before the build and names the file to move, which also makes this case impossible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant