wso2 / wso2/api-platform

[Improvement]: REST API listing endpoint should return a slim list item instead of the full RESTAPI schema

Open
#3,392 0 comments 0 reactions 1 assignee View on GitHub

@ShavinAnjithaAlpha is already working on this.

Since Sep 7, 2026.

Aspect/API Type/Improvement
Dominant language
Go
Stars
71
Forks
111
Avg merge
1d 14h
Merged PRs (30d)
110

Description

Please select the area the issue is related to

Platform API

Please select the aspect the issue is related to

Aspect/API (API backends, definitions, contracts, interfaces, OpenAPI)

Suggested Improvement
Current limitation

GET /api/v0.9/rest-apis (ListRESTAPIs) returns RESTAPIListResponse, whose list items are the full RESTAPI schema, the same payload as the single-resource detail endpoint GET /rest-apis/{restApiId}:

platform-api/resources/openapi.yaml

RESTAPIListResponse:
  properties:
    list:
      type: array
      items:
        $ref: '#/components/schemas/RESTAPI'   # full detail schema

That means every item in a listing carries the entire API definition:

  • operations[] — every resource/method with its own policies[], scopes, auth config, etc.
  • policies[] — the full API-level policy chain with params
  • upstream — backend URL(s), auth/TLS configuration, resolved {{ secret "..." }} references
  • channels[], subscriptionPlans[], transport[]

A listing view only needs identity/summary information: id, displayName, description, context, version, projectId, lifeCycleStatus, kind, readOnly, createdBy, createdAt, updatedAt.

Impact

  1. Response size / latency. An API with 50–100 operations, each with its own policy list, produces a very large object. Multiply by limit and a single listing request returns megabytes of JSON that no list UI renders. This is the payload the API listing page in the control-plane portal and ap CLI fetch on every page load.
  2. Wasted DB and CPU work. Full configuration blobs are read from the DB and JSON-unmarshalled for every row, only to be discarded by the caller.
  3. N+1 project lookup. modelToRESTAPIUnresolved calls projectRepo.GetProjectByUUID once per API in the loop just to resolve projectId to a project handle, even though the listing is already filtered to a single project (projectId is a required query parameter). One resolution per page would suffice.
  4. Over-exposure of configuration detail. Backend upstream URLs, auth configuration, and full policy parameters are returned to anyone holding ap:rest_api:read, on an endpoint that is meant to enumerate APIs. Detail-level configuration should be fetched deliberately via the detail endpoint.

Notably, updatedBy is already being stripped from list responses in the service layer (apiResponse.UpdatedBy = nil) with the OpenAPI description noting it is "Only present in the detail response"; a field-by-field workaround that shows the list and detail representations have already diverged in practice, just without a schema to express it.

Suggested improvement

Introduce a dedicated RESTAPIListItem schema for the listing response, following the pattern already established elsewhere in the same spec:

  • MCPProxyListItem → used by MCPProxyListResponse
  • LLMProxyListItem → used by LLMProxyListResponse
  • LLMProviderListItem → used by LLMProviderListResponse
  • SecretSummary → used by SecretListResponse

REST APIs are the outlier still returning the full detail schema in a collection response.

Proposed shape:

RESTAPIListItem:
  type: object
  required:
    - displayName
    - context
    - version
    - projectId
  properties:
    id: { type: string }
    displayName: { type: string }
    description: { type: string }
    context: { type: string }
    version: { type: string }
    projectId: { type: string }
    kind: { type: string }
    lifeCycleStatus: { type: string, enum: [STAGED, CREATED, PUBLISHED, DEPRECATED, RETIRED, BLOCKED] }
    readOnly: { type: boolean, readOnly: true }
    createdBy: { type: string, readOnly: true }
    createdAt: { type: string, format: date-time, readOnly: true }
    updatedAt: { type: string, format: date-time, readOnly: true }

RESTAPIListResponse:
  properties:
    list:
      type: array
      items:
        $ref: '#/components/schemas/RESTAPIListItem'
Related Issues

https://github.com/wso2/api-platform/issues/3391

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.