Many times, you might have multiple versions of an API that you want to expose to end users. With Gloo Portal’s flexible approach to portal metadata, you can provide support phases, compatibility, usage plans, terms of service, licensing, and other lifecycle management information for each API version. Then, you can bundle multiple API versions into a single API product.

Before you begin

  1. Make sure that your cluster name is set as an environment variable.
      echo $CLUSTER_NAME
      
  2. Get the external address of your ingress gateway. The steps vary depending on the type of load balancer that backs the ingress gateway.

     ```shell
     export INGRESS_GW_ADDRESS=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
     echo $INGRESS_GW_ADDRESS
     ```
    

    Note: Depending on your environment, you might see <pending> instead of an external IP address. For example, if you are testing locally in kind or minikube, or if you have insufficient permissions in your cloud platform, you can instead port-forward the service port of the ingress gateway:

      kubectl -n gloo-mesh-gateways port-forward deploy/istio-ingressgateway-1-18 8081
      

Step 1: Deploy two versions of your API

The following example application has two versions. In one version, the app returns the color blue. In the other version, the app returns the color green. Each app has its own workload and service.

  1. Create the Blue app. To review the service and deployment, see the GitHub source file.

      kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/color-app-blue.yaml
      
  2. Create the Green app. To review the service and deployment, see the GitHub source file.

      kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/color-app-green.yaml
      
  3. Verify that your color apps are running.

      kubectl get all -l app=color
      
  4. Create an ApiDoc resource for each app. An ApiDoc is a simple way to add an OpenAPI schema to your app. If your app has a path such as swagger.json or a remote URL to fetch the OpenAPI schema from, you could use automatic discovery instead. For more information, see Create your APIs.

  5. Verify that the ApiDocs are created with an OpenAPI spec for each of your color apps.

      kubectl get apidocs -o=jsonpath='{range .items[*]}[{.metadata.name}, {.spec.openapi.inlineString}]{"\n"}{end}' 
      

    Example output:

      [color-blue, {"openapi":"3.0.0","info":{"title":"Blue Endpoint API","version":"1.0.0","description":"API for the /blue endpoint that returns the color of the serving pod."},"paths":{"/blue":{"get":{"summary":"Get the color of the serving pod","description":"Returns the color of the serving pod.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"color":{"type":"string","description":"The color of the serving pod. This value is dynamically generated by the server."}}}}}}}}}}}]
    
    [color-green, {"openapi":"3.0.0","info":{"title":"Green Endpoint API","version":"1.0.0","description":"API for the /green endpoint that returns the color green."},"paths":{"/green":{"get":{"summary":"Get the color green","description":"Returns the color green as the response.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"color":{"type":"string","example":"green","description":"The color green is returned as the response."}}}}}}}}}}}]
      

Step 2: Set up portal routing to your APIs

You have two versions of your color app, blue and green. You can group these versions together into a single API product with lifecycle management details for your end users.

  1. Create a route table to represent each API version of your color apps.

    Review the following table to understand this configuration. For more information, see the API docs.

    SettingDescription
    NamespaceCreate the route table in the same namespace, or import it into the same Gloo workspace as the ingress gateway. In this example, the route table is in the same namespace as the ingress gateway, gloo-mesh-gateways.
    LabelsInclude labels to help select this route table with other portal resources later. This example has two labels. The portal: dev-portal label can be used to associate this route table as part of the dev-portal collection of Gloo resources, while the app: color labels can be used to associate this route table more specifically with the different Color APIs.
    HTTP name and labelsName your route and add a label that you can use to apply the policies of your usage plan to the route later. In this example, the Reviews routes have three labels: usagePlans: dev-portal, app: color, and a color label unique to each version.
    HTTP matchers and forwardTo for the routeFor each app that you want to expose APIs for, define the route matchers that you want the APIs to be available on. This example defines the /blue or /green route for each version. Then, these routes are available on the matching host, such as colors.com/blue or colors.com/green.
    Portal metadataA set of key-value pairs that describe your API, which you put together in the previous step. At a minimum, each route table for an API version must have a unique apiVersion but the same apiProductId to group the versions together. You can also include other portal metadata, as shown in the following example. Later, your developer portal displays this information in the end-user facing API documentation. For more information about each setting, see the API docs.
  2. Create a route table for the domain that you want your API products to be exposed on. This route table delegates the routing rules for matching HTTP routes to the route tables that you previously created. Note that the following example does not set any portal metadata, because that information is set per API product in the delegated route tables.

      kubectl apply -f - << EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: colors-com-rt
      namespace: gloo-mesh-gateways
    spec:
      hosts:
      - colors.com
      virtualGateways:
      - name: color-ingressgateway
        namespace: gloo-mesh-gateways
        cluster: $CLUSTER_NAME
      http:
      - matchers:
        - uri:
            prefix: /       
        delegate:
          routeTables:
            - labels:
                app: color
    EOF
      

    Review the following table to understand this configuration. For more information, see the API docs.

    SettingDescription
    NamespaceCreate the route table in the same namespace or import it into the same Gloo workspace as the ingress gateway. In this example, the route table is in the same namespace as the ingress gateway, gloo-mesh-gateways.
    HostsAdd the host domains that you want the API products to be exposed on, such as colors.com.
    Virtual gatewaySelect the virtual gateway with the host that you want to use to expose your apps’ APIs. In this example, you select a virtual gateway that you create in the next step.
    HTTP matchers and delegationsFor each API product that you want to expose on the host domain, set up matchers and delegated route tables. In this example, requests that match / are delegated to the app: color route tables.
  3. Create a virtual gateway for the host domain that you want to expose your API products on. The following example configures a simple HTTP gateway. For more examples such as HTTPS/TLS, see Configure gateway listeners.

      kubectl apply -f - << EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      name: color-ingressgateway
      namespace: gloo-mesh-gateways
    spec:
      listeners:
        - port:
            number: 80
          http: {}
          allowedRouteTables:
            - host: colors.com
      workloads:
      - selector:
          labels:
            istio: ingressgateway
          cluster: $CLUSTER_NAME
    EOF
      

    Review the following table to understand this configuration. For more information, see the API docs.

    SettingDescription
    Listener’s allowed route tablesAdd the host domain that matches the route table for the API products that you want to expose. In this example, the colors.com matches the host in the domain-level route table that you created to expose together your Reviews API product.
  4. Verify that you can reach both versions of your color app. The following example sends a curl request to each of the API versions that you set up. Note that the routes are not yet secured. You secure the routes with rate limiting and external auth policies later as part of your portal’s usage plan.

Step 3: Verify your API product in the frontend portal

Now, you have multiple versions of your API product. Your end users can review each API version’s metadata, such as lifecycle management, as part of the API product in your frontend portal.

  1. Create a frontend developer portal.
  2. Interact with the developer portal as an end user to discover your API products.
  3. Verify that the Colors API Product has both API versions for blue and green.
Figure: Color API products in the frontend developer portal
Figure: Color API products in the frontend developer portal

Cleanup

You can optionally remove the resources that you set up as part of this guide.

  1. Delete your color apps.
      kubectl delete all -l app=color
      
  2. Delete the domain-level colors.com route table along with the delegated routes tables for the versions of your color apps.
      kubectl delete rt -n gloo-mesh-gateways colors-com-rt
    kubectl delete rt -n gloo-mesh-gateways color-blue
    kubectl delete rt -n gloo-mesh-gateways color-green
      
  3. Delete the virtual gateway for your colors.com domain.
      kubectl delete vg -n gloo-mesh-gateways color-ingressgateway