Skip to content

Function Routing

What you'll need

If you haven't already deployed Gloo and the example swagger service on kubernetes, go back to the first tutorial

Now that we've seen the traditional routing functionality of Gloo (i.e. API-to-service), let's try doing some function routing.

Let's take a look at the upstream that was created for our petstore service:

     glooctl upstream get default-petstore-8080 -o yaml

     functions:
     - name: addPet
       spec:
         body: '{"id": {{id}},"name": "{{name}}","tag": "{{tag}}"}'
         headers:
           :method: POST
         path: /api/pets
     - name: deletePet
       spec:
         body: ""
         headers:
           :method: DELETE
         path: /api/pets/{{id}}
     - name: findPetById
       spec:
         body: ""
         headers:
           :method: GET
         path: /api/pets/{{id}}
     - name: findPets
       spec:
         body: ""
         headers:
           :method: GET
         path: /api/pets?tags={{tags}}&limit={{limit}}
     ...

We can see there are functions on our default-petstore-8080 upstream. These functions were populated automatically by the function-discovery pod. You can see the function discovery service in action by running kubectl logs -l gloo=function-discovery

The function spec you see on the functions listed above belongs to the transformation plugin. This powerful plugin configures Gloo's request/response transformation Envoy filter to perform transform requests to the structure expected byour petstore app.

In a nutshell, this plugin takes Inja templates for HTTP body, headers, and path as its parameters (documented in the plugin spec and transforms incoming requests from those templates. Parameters for these templates can come from the request body (if it's JSON), or they can come from parameters specified in the extensions on a route.

Let's see how this plugin works by creating some routes to these functions in the next section.


Steps

  1. Start by creating the route with glooctl:

    glooctl route create \
      --path-exact /petstore/findPet \
      --upstream default-petstore-8080 \
      --function findPetById
    

    Notice that, unlike the previous tutorial, we're passing an extra argument to glooctl: --function findPetById.

    Let's go ahead and test the route using curl:

    export GATEWAY_URL=http://$(minikube ip):$(kubectl get svc ingress -n gloo-system -o 'jsonpath={.spec.ports[?(@.name=="http")].nodePort}')
    
    curl ${GATEWAY_URL}/petstore/findPet
    
    bad request: Did not found json element: id
    

    What's that? An error? Try again with curl -v and you'll see a 400 Bad Request status on the response.

    Looking again at the function findPetById, you'll notice the template wants a variable called id:

     - name: findPetById
       spec:
         body: ""
         headers:
           :method: GET
         path: /api/pets/{{id}}
    
  2. Try the request again, but now add a JSON body with the parameter specified by name:

    curl ${GATEWAY_URL}/petstore/findPet -d '{"id": 1}'
    
    {"id":1,"name":"Dog","status":"available"}
    

    Great! We just called our first function through Gloo.


  3. Parameters can also come from headers. Let's tell Gloo to look for id in a custom header.

    Let's take a look at the route we created:

    glooctl route get -o yaml
    
    Using virtual service: default
    request_matcher:
      path_exact: /petstore/findPet
    single_destination:
      function:
        function_name: findPetById
        upstream_name: default-petstore-8080
    

    We need to add an extension to this route that tells Gloo how to grab template parameters from the request.

    Add parameters to the route's extensions like so:

    cat <<EOF | glooctl route update --old-path-exact /petstore/findPet --old-upstream default-petstore-8080 --old-function findPetById --path-exact /petstore/findPet --upstream default-petstore-8080 --function findPetById --extensions -
    parameters:
      headers:
        x-pet: '{id}'
    EOF
    

    Now Gloo knows to look for the parameter named id in a header called x-pet.

    Try curl again, this time with the new header:

    curl ${GATEWAY_URL}/petstore/findPet -H "x-pet: 1"
    
    {"id":1,"name":"Dog","status":"available"}
    

Tutorials for more advanced use-cases are coming soon. In the meantime, please see our plugin documentation for a list of available plugins and their configuration options.