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.
-
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 a400 Bad Request
status on the response.Looking again at the function
findPetById
, you'll notice the template wants a variable calledid
:- name: findPetById spec: body: "" headers: :method: GET path: /api/pets/{{id}}
-
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.
-
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'sextensions
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 calledx-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.