Create an API Product

API Products are a Kubernetes Custom Resource which bundles the APIs defined in API Docs into a product that can be exposed to ingress traffic as well as published on a Portal UI. The Product defines what API operations are being exposed, and the routing information to reach the services.

In this guide, you will create an API Product and add operations from an API Doc using the Admin Dashboard.

Pre-requisites

You will need to have the Gloo Portal deployed on a Kubernetes cluster, and a connection to the Admin Dashboard as described in the Using the Admin Dashboard guide. You will also need an API Doc created through the Create an API Doc guide.

Finally, you will need an instance of the Petstore application deployed on Kubernetes. If you don’t already have an instance created, go ahead and run the following command:

kubectl apply -n default -f \
  https://raw.githubusercontent.com/solo-io/gloo/v1.3.7/example/petstore/petstore.yaml
kubectl -n default rollout status deployment petstore

Create an API Product

We will start from the Overview page of the Gloo Portal. First you will click on the APIs item in the navigation bar to manage API Docs, Products, Routes, and more.

Admin Dashboard Nav Bar

The page should load on the API Products category by default. Next you click on the Create an API button to start the process.

Admin Dashboard Create API

On the General page, you will fill out the basic fields for the API Product.

Admin Dashboard Create API General

In our example we are going to use the following values:

Then click on Next Step to move to the Domains page. Domains are fully-qualified addresses where the API Product should be made available.

Admin Dashboard Create API Domains

We can use the domain api.example.com for our example, but obviously you can use whatever domain makes sense for your application.

Then click on Next Step to move to the Imagery page. The is the image that will be displayed in the Portal UI alongside the API Product.

Admin Dashboard Create API Imagery

We are going to add an image from a URL. To do so, click on Upload an Image and paste in the value: https://i.imgur.com/Co2A5lK.png then click on OK in the file dialog box. The downloaded image will appear on the screen.

Admin Dashboard Create API Upload

Then click on Next Step to move to the API Docs page. On this page you can select which API Docs to include in the API Product, as well as any specific operations from the API Doc.

Admin Dashboard Create API Docs

For our example, click on the box next to Swagger Petstore to select all of the operations.

And finally click Create API Product to complete the process.

Create a route

In the Getting Started example, we used the following code snippet in the API Product YAML to associate the product with a default route to the service:

  defaultRoute:
    inlineRoute:
      backends:
      - kube:
          name: petstore
          namespace: default
          port: 8080

When creating the API Product through the UI, the product does not yet have a route associated with the operations selected from the API Doc(s). If you click on the Petstore Product v2 API Product, you’ll see the following notice displayed prominently at the top:

Admin Dashboard Create API Route Warning

We can either choose to set a default route for the entire API Product - as we did in the Getting Started example - or set individual routes for each operation from the API Doc(s). For our example, you are going to create a default route for the entire API Product and apply it.

First, you will need to close the Petsore Product v2 view if you have it open, and then select the Routes category from the left-side menu.

Admin Dashboard Create Route

Next you will click on the Create a Route button to start the route creation wizard.

Admin Dashboard Create Route Button

On the General page of the New Route wizard you will fill out the Name of the route and the Namespace in which you want the route resource to be created.

Admin Dashboard Create Route General

In our example, we will use the name petstore-v2 and the namespace default.

Now click on Next Step to get to the Header Manipulation page. This page allows you to set header manipulations for the request or response. We are not going to set anything on this page.

Admin Dashboard Create Route General

Now click on Next Step to get to the Destinations page. This page defines one or more destinations for the route in the namespace selected on the prior page.

Admin Dashboard Create Route Destination

From the Add Destinations list on the left, find the petstore (8080) destination.

Admin Dashboard Create Route Destination Select

Click on the green plus button to add it to the Selected Destinations list.

Admin Dashboard Create Route Destination Selected

And click on Next Step to move to the Weight page.

Admin Dashboard Create Route Weight

Had we selected multiple destinations on the previous page, we could assign different weights to each destination. There is only one destination in our example, so leave the value set to 1 and click on Create Route to finish the route creation process.

Admin Dashboard Create Route Complete

The next step is to associate this route as the default route for the Petstore Product v2 API Product.

Associate the route

We are going to go back into the API Product area to edit the existing Petstore Product v2 API product. Click on the API Products category in the left-side menu.

Admin Dashboard Edit API Product

Then select Petstore Product v2 from the API Products list.

Admin Dashboard Edit API Product

On the product page, you will click on the Edit icon to edit the properties of the API Product.

Admin Dashboard Edit API Product

Under Default Route click on the dropdown list and select petstore-v2.

Admin Dashboard Edit API Product Default

Then click on the Save Changes button to complete your changes.

Admin Dashboard Edit API Product Save

Finally, click on the Routes Enabled toggle to enable routing for the API Product.

Admin Dashboard Edit API Product Enable Route

Now the warning should disappear from the display, and the API Product is all ready to go!

Test our API using cURL

Now that we have exposed our API Product for routing, we should be able to make client requests to the product APIs.

Let’s get the address of the Gateway. Choose the option corresponding to your Ingress Service Type:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export INGRESS_HOST=$(kubectl -n gloo-system get service gateway-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n gloo-system get service gateway-proxy -o jsonpath='{.spec.ports[?(@.name=="http")].port}')
export INGRESS_HOST=$(kubectl get po -l gloo=gateway-proxy -n gloo-system -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n gloo-system get service gateway-proxy -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}')

With the Ingress address, we can now try to call one of our published operations:

curl "http://${INGRESS_HOST}:${INGRESS_PORT}/api/pets" -H "Host: api.example.com"

We should see the output:

[{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}]

This means that the API Product and routes are configured correctly.

Using kubectl

If you wanted to create the same API Product and route using kubectl you could do so by submitting two new Custom Resources.

First you would create the route CR with the following command:

cat <<EOF | kubectl apply -f -
apiVersion: devportal.solo.io/v1alpha1
kind: Route
metadata:
  name: petstore-v2
  namespace: default
spec:
  backends:
  - kube:
      name: petstore
      namespace: default
      port: 8080
    weight: 1
EOF

Then you could create the API Product with the following command:

cat << EOF | kubectl apply -f-
apiVersion: devportal.solo.io/v1alpha1
kind: APIProduct
metadata:
  name: petstore-product-v2
  namespace: dev-portal
spec:
  apis:
  - apiDoc:
      name: swagger-petstore
      namespace: dev-portal  
  defaultRoute:
    routeRef:
      name: petstore-v2
      namespace: default
  domains:
  - api.example.com
  publishRoutes: true
  displayInfo: 
    description: Petstore Product v2
    title: Petstore Product v2
    version: "2.0"
    image:
      fetchURL: https://i.imgur.com/Co2A5lK.png

EOF

Next Steps

Now that you have successfully created an API Product, there are a few options. You can create users and groups and grant them access to the API Product through a Usage Plan, or you can create a Portal UI and add the API Product to it.