Skip to content

fix: accept integer reference ids from the Admin API - #3472

Merged
guoqqqi merged 3 commits into
apache:masterfrom
janiussyafiq:fix/resource-ref-numeric-id
Sep 1, 2026
Merged

guoqqqi merged 3 commits into
apache:masterfrom
janiussyafiq:fix/resource-ref-numeric-id

Conversation

@janiussyafiq

@janiussyafiq janiussyafiq commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Why submit this pull request?

  • Bugfix
  • New feature provided
  • Improve performance
  • Backport patches

What changes will this PR take into?

The gateway's id_schema is anyOf [string, integer] and it stores the JSON type the writer sent, so a route created by another client with "plugin_config_id": 10001 reads back with a number in that field, and PUT /apisix/admin/routes with "id": 10001 in the body stores a numeric primary id. Since #3459, ResourceRef calls .trim() on that value and every detail page that renders a reference field (routes, stream routes, services, consumers) crashes to "Something went wrong"; before #3459 the page rendered but Save failed with "Expected string, received number".

  • Add APISIXCommon.RefId (string or positive integer, normalized to a string) and use it for every id-typed field: the resource's own id, upstream_id, service_id, plugin_config_id, script_id, group_id, client_cert_id, superior_id.
  • ResourceRef reads the id through toRefId, so the raw number the form holds before validation no longer throws.
  • protos/detail lets zodResolver infer the form types like the other detail pages do, since the schema now carries a transform.
  • Tests: a gateway-contract check that every anyOf [string, integer] field, nested ones included, accepts the integer form; unit tests for RefId, ID and toRefId; an e2e spec that seeds numeric ids through the Admin API and verifies render, resolved link and save for a route (with a numeric primary id), a stream route, a service and a consumer.

Related issues

fix #3471, close #3470

Checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first

The gateway's `id_schema` is `anyOf [string, integer]` and it stores the
JSON type the writer sent, so a route created by another client with
`"plugin_config_id": 10001` reads back with a number in that field.
`ResourceRef` called `.trim()` on it and took the whole detail page down
to the root error boundary, and before that the resolver refused to save
such a resource with "Expected string, received number".

Model every reference field with a shared `RefId` that accepts both forms
and normalizes to a string, and make `ResourceRef` tolerate the raw value
the form holds before validation runs.

fix apache#3471, close apache#3470
`PUT /apisix/admin/routes` with `"id": 10001` in the body and no id in the
URL stores and returns a numeric primary id, so `ID.id` takes the same
`RefId` as the reference fields and the contract test no longer allowlists
it. The contract check now walks nested objects as well
(`upstream.tls.client_cert_id`, `protocol.superior_id`), the `RefId` unit
tests live in `common.test.ts`, and the e2e spec covers a route with a
numeric primary id and a stream route.
@guoqqqi
guoqqqi merged commit fa2fd0f into apache:master Sep 1, 2026
6 checks passed
@janiussyafiq
janiussyafiq deleted the fix/resource-ref-numeric-id branch September 1, 2026 02:34
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.

bug: Dashboard:045e3142867e3b7d5d1b8ec40bf8f66a7ce24a64 trim is not a function (s ?? "").trim is not a function

3 participants