Skip to content

Basic Routing

What you'll need

Steps

Step 1

Install and run gloo services on Docker. Please visit installing on Docker for more details.

Step 2

Deploy the Pet Store app:

docker run -d -p 9000:8080 soloio/petstore-example:latest

Step 3

Since Docker doesn't have any service registry, gloo doesn't support automatic upstream discovery in Docker environment. We need to manually create an upstream with glooctl

cat << EOF | glooctl upstream create -f -
name: petstore
type: static
spec:
  hosts:
  # gateway ip for the docker network
  - addr: $(docker inspect docker-compose_default -f '{{ (index .IPAM.Config 0).Gateway }}')  
    port: 9000
EOF

You should see a new upstream has been created.

+----------+---------+--------+----------+
|   NAME   |  TYPE   | STATUS | FUNCTION |
+----------+---------+--------+----------+
| petstore | static |        |          |
+----------+---------+--------+----------+

Verify that the upstream has been created.

glooctl upstream get

+----------+---------+----------+-------------+
|   NAME   |  TYPE   |  STATUS  |  FUNCTION   |
+----------+---------+----------+-------------+
| petstore | static | Accepted | addPet      |
|          |         |          | deletePet   |
|          |         |          | findPetById |
|          |         |          | findPets    |
+----------+---------+----------+-------------+

Let's take a closer look at the functions that are available on this upstream (edited here to reduce verbosity)

glooctl upstream get petstore -o yaml

functions:
- name: addPet
  spec:
    body: '{"id": {{ default(id, "") }},"name": "{{ default(name, "")}}","tag": "{{
      default(tag, "")}}"}'
    headers:
      :method: POST
      Content-Type: application/json
    path: /api/pets
- name: deletePet
  spec:
    body: ""
    headers:
      :method: DELETE
    path: /api/pets/{{ default(id, "") }}
- name: findPetById
  spec:
    body: ""
    headers:
      :method: GET
    path: /api/pets/{{ default(id, "") }}
- name: findPets
  spec:
    body: ""
    headers:
      :method: GET
    path: /api/pets?tags={{default(tags, "")}}&limit={{default(limit, "")}}
metadata:
  annotations:
    gloo.solo.io/discovery-type: swagger
    gloo.solo.io/swagger_url: http://10.74.150.107:9000/swagger.json
  resource_version: "1"
name: petstore
service_info:
  type: REST
spec:
  hosts:
  - addr: 10.74.150.107
    port: 9000
status:
  state: Accepted
type: static

Step 4

Let's now use glooctl to create a route for this upstream.

glooctl route create \
  --path-exact /petstore/list \
  --upstream petstore \
  --prefix-rewrite /api/pets

This should result in a new route being created.

Did not find a default virtual service. Creating...
Using virtual service: default
+----------------+------------+------+--------+----------+----------+-----------+
|    MATCHER     |    TYPE    | VERB | HEADER | UPSTREAM | FUNCTION | EXTENSION |
+----------------+------------+------+--------+----------+----------+-----------+
| /petstore/list | Exact Path | *    |        | petstore |          |           |
+----------------+------------+------+--------+----------+----------+-----------+

We need the --prefix-rewrite flag so Envoy knows to change the path on the outgoing request to the path our petstore expects.

With glooctl, we can see that a virtual service was created with our route:

glooctl virtualservice get -o yaml

---
metadata:
  resource_version: "1"
name: default
routes:
- prefix_rewrite: /api/pets
  request_matcher:
    path_exact: /petstore/list
  single_destination:
    upstream:
      name: petstore
status:
  state: Accepted

Step 5

Let's test the route /petstore/list using curl:

curl http://127.0.0.1:8080/petstore/list

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

The address of 127.0.0.1:8080 is the gateway (Envoy) address.

Great! our gateway is up and running. Let's make things a bit more sophisticated in the next section with Function Routing.