Skip to content
You are viewing the latest documentation for Solo Enterprise for kgateway. To access the documentation for older versions, use the version switcher.

Create ApiProducts

Page as Markdown

Bundle your APIs into versioned ApiProducts and expose them in the portal catalog.

This guide must be completed by a Portal admin.

An ApiProduct is a logical API offering that groups one or more versions of an API. Each version references an HTTPRoute that serves that version’s traffic. The portal controller automatically links the HTTPRoute’s backend services to their ApiDocs and stitches the schemas together into a single generated ApiDoc per version so that they can be rendered in the portal frontend.

You do not reference ApiDocs directly in an ApiProduct. The controller discovers them implicitly through the HTTPRoute’s backend services as shown in this diagram.

    flowchart LR
    APV[ApiProduct Version] -->|targetRefs| HR[HTTPRoute]
    HR -->|backendRefs| Svc[Service]
    AD[ApiDoc] -->|servedBy| Svc
    APV -.->|controller generates| SAD[Stitched ApiDoc]
  
  1. An ApiProduct version references one or more HTTPRoutes via the targetRefs field.
  2. The portal controller examines each HTTPRoute’s backendRefs to find the backend services.
  3. The portal controller finds the ApiDocs that are served by these services by using the servedBy field.
  4. The portal controller stitches the matching schemas together into a single generated ApiDoc per version.

Before you begin

  1. Follow the Get started guide to install Solo Enterprise for kgateway.
  2. Set up a portal.
  3. Create an ApiDoc for your service. The example in this guide uses the petstore app.

Create an ApiProduct

Create an ApiProduct and define one or more versions of your API. Each version references the HTTPRoute that serves that version of the API.

Single API version

Create an ApiProduct with a single version of the petstore API. The ApiProduct references the petstore HTTPRoute that you created before you began.

kubectl apply -f- <<EOF
apiVersion: portal.solo.io/v1alpha1
kind: ApiProduct
metadata:
  name: petstore-api
  namespace: default
spec:
  id: petstore
  displayName: "Petstore API"
  customMetadata:
    category: "Pet Management"
  versions:
  - name: v1
    targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: petstore-route
    openApiMetadata:
      title: "Petstore API"
      description: "Manage your pets"
EOF
SettingDescription
idA URL-safe unique identifier for the ApiProduct (1–128 characters). This ID is used to construct the API URL in the portal API catalog.
displayNameHuman-readable name for that API that is displayed in the portal UI.
customMetadataOptional arbitrary key-value pairs that are surfaced in the portal UI. You can have a maximum of 16 entries.
versions[].nameThe version identifier, such as v1 or v2.
versions[].targetRefsReference the HTTPRoutes that serve this version.
versions[].openApiMetadataOptional metadata that are merged into the stitched OpenAPI schema for this version. This information is displayed in the portal UI when you select this API version.

Multiple API versions

An ApiProduct can expose multiple API versions simultaneously. Each version references its own HTTPRoute independently. The portal UI displays a version selector for products with multiple versions.

  1. Create a second HTTPRoute for the v2 version of the API. Make sure to use a unique matcher so that requests can be correctly routed to this version. The matcher must be different from the matcher that you use for the v1 version of the API.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: petstore-v2-route
      namespace: default
    spec:
      parentRefs:
      - name: portal-gateway
        namespace: default
      hostnames:
      - "api.example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /petstore/v2
        filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /
        backendRefs:
        - name: petstore
          port: 8080
    EOF
  2. Create the ApiProduct and include both versions of your API.

    kubectl apply -f- <<EOF
    apiVersion: portal.solo.io/v1alpha1
    kind: ApiProduct
    metadata:
      name: petstore-api
      namespace: default
    spec:
      id: petstore
      displayName: "Petstore API"
      versions:
      - name: v1
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: HTTPRoute
          name: petstore-route
        openApiMetadata:
          title: "Petstore API v1"
          description: "Manage your pets"
      - name: v2
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: HTTPRoute
          name: petstore-v2-route
        openApiMetadata:
          title: "Petstore API v2"
          description: "Manage your pets (v2)"
    EOF
  3. Verify that a stichted ApiDoc is generated for each version of the API. Each version gets its own generated ApiDoc named <apiproduct-name>-<version-name>.

    kubectl get apidocs -A 

    Example output:

    NAMESPACE   NAME                  SOURCE     READY   AGE
    default     petstore-api-v1       Stitched   True    1m
    default     petstore-api-v2       Stitched   True    1m
    default     petstore-url-apidoc   Url        True    1m

Add the ApiProduct to the portal

Update the Portal resource to include the ApiProduct in its catalog. The portal controller regenerates the PortalConfig after you update the Portal.

Reference an ApiProduct in the same namespace as the Portal.

kubectl apply -f- <<EOF
apiVersion: portal.solo.io/v1alpha1
kind: Portal
metadata:
  name: my-portal
  namespace: default
spec:
  parametersRef:
    name: portal-params
  visibility:
    public: true
  apiProductRefs:
  - name: petstore-api
  - name: httpbin-api
EOF

Reference an ApiProduct in a different namespace by specifying the namespace field. Cross-namespace references require a ReferenceGrant in the target namespace to authorize the reference.

  1. Create a ReferenceGrant in the namespace where the ApiProduct lives (other-namespace) to allow the Portal in the default namespace to reference it.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: ReferenceGrant
    metadata:
      name: portal-apiproduct-grant
      namespace: other-namespace
    spec:
      from:
      - group: portal.solo.io
        kind: Portal
        namespace: default
      to:
      - group: portal.solo.io
        kind: ApiProduct
    EOF
  2. Create the Portal and reference the ApiProduct in other-namespace.

    kubectl apply -f- <<EOF
    apiVersion: portal.solo.io/v1alpha1
    kind: Portal
    metadata:
      name: my-portal
      namespace: default
    spec:
      parametersRef:
        name: portal-params
      visibility:
        public: true
      apiProductRefs:
      - name: petstore-api
        namespace: other-namespace
      - name: httpbin-api
    EOF

Include all ApiProducts in a namespace by using a wildcard for the name field.

kubectl apply -f- <<EOF
apiVersion: portal.solo.io/v1alpha1
kind: Portal
metadata:
  name: my-portal
  namespace: default
spec:
  parametersRef:
    name: portal-params
  visibility:
    public: true
  apiProductRefs:
  - name: "*"
    namespace: default
EOF

Verify your ApiProduct

  1. List the ApiProducts and ApiDocs in your namespace. For each ApiProduct version, the controller generates a stitched ApiDoc that is named <apiproduct-name>-<version-name>.

    kubectl get apiproduct,apidoc -n default

    Example output:

    NAME                                     ID         DISPLAY NAME   READY
    apiproduct.portal.solo.io/petstore-api   petstore   Petstore API   True
    
    NAME                                        SOURCE     READY   AGE
    apidoc.portal.solo.io/petstore-api-v1       Stitched   True    24m
    apidoc.portal.solo.io/petstore-api-v2       Stitched   True    7m21s
    apidoc.portal.solo.io/petstore-url-apidoc   Url        True    22h
  2. If an ApiProduct does not show Ready=True, describe the resource to see the error details.

    kubectl describe apiproduct petstore-api -n default
  3. Verify that the PortalConfig was updated with the ApiProduct. The spec.apis field must contain an entry for each ApiProduct version and a reference to the generated stitched ApiDoc resource.

    kubectl get portalconfig my-portal -n default -o yaml

    Example output:

    ...
    spec:
      apis:
      - apiDocRef:
         name: petstore-api-v1
          namespace: default
        apiProductDisplayName: Petstore API
       apiProductId: petstore
        apiVersion: v1
        description: Manage your pets
        title: Petstore API v1
      - apiDocRef:
          name: petstore-api-v2
          namespace: default
        apiProductDisplayName: Petstore API
        apiProductId: petstore
        apiVersion: v2
        description: Manage your pets (v2)
        title: Petstore API v2
      - apiDocRef:
          name: httpbin-api-v1
          namespace: default
        apiProductCustomMetadata:
          category: Utilities
        apiProductDisplayName: HTTPBin API
        apiProductId: httpbin
        apiVersion: v1
        description: A simple HTTP request/response service for testing
        title: HTTPBin API
      portalMetadata:
        name: my-portal
Was this page helpful?