HTTP Method Matching

The route rules in a Virtual Service can evaluate based on the request HTTP method, e.g. GET, POST, DELETE, etc. You can specify one or more HTTP Methods to match against, and if any one of those method verbs is present, the request will match, that is Gloo will conditional OR the match for HTTP Method.

Gloo/Envoy is based on HTTP/2, the HTTP method gets translated into a header value match against the HTTP/2 :method header, which by spec includes all of the HTTP/1 verbs.

In this guide, we’re going to take a closer look at different method matches by creating an Upstream and then creating a Virtual Service to route requests to that Upstream based on the method used in the request.


Setup

If you have not yet deployed Gloo, you can start by following the directions contained within the guide Installing Gloo Gateway on Kubernetes.

This guide also assumes that you are running Gloo Gateway in a Kubernetes cluster. Each example can be adapted to alternative deployments, such as using the HashiCorp stack of Nomad, Consul, and Vault.

This guide assumes that you have deployed Gloo to the gloo-system namespace and that the glooctl command line utility is installed on your machine. glooctl provides several convenient functions to view, manipulate, and debug Gloo resources; in particular, it is worth mentioning the following command, which we will use each time we need to retrieve the URL of the Gloo Gateway that is running inside your cluster:

glooctl proxy url

Create an Upstream

First we are going to create a simple Upstream for testing called json-upstream, that routes to a static site.


apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
  name: json-upstream
  namespace: gloo-system
spec:
  static:
    hosts:
      - addr: jsonplaceholder.typicode.com
        port: 80

glooctl create upstream static --static-hosts jsonplaceholder.typicode.com:80 --name json-upstream

Create a Virtual Service

Our next step is to create a series of Virtual Services to test the POST and GET method matchers. We will first create a new Virtual Service for the POST method. Then delete that Virtual Service and create a second one for the GET method.

Create the POST Virtual Service

Let’s create a Virtual Service with an http method match on POST on the prefix /. This route rule will match on requests that use the POST method and reference any path that starts with /, i.e. all paths on the Upstream.


apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: test-post
  namespace: gloo-system
spec:
  virtualHost:
    domains:
      - 'foo'
    routes:
      - matchers:
         - methods:
            - POST
           prefix: /
        routeAction:
          single:
            upstream:
              name: json-upstream
              namespace: gloo-system
        options:
          autoHostRewrite: true

Now let’s send a POST request to that route and make sure we receive a valid response.

curl -H "Host: foo" -XPOST $(glooctl proxy url)/posts

returns

{
  "id": 101
}

The response confirms that a new blog post was created on the Upstream.

Now let’s delete that virtual service to prepare for the next method.


kubectl delete vs -n gloo-system test-post

glooctl delete vs --name test-post

Create the GET Virtual Service

We’ve seen how the POST method matches, now let’s create a virtual service that matches on GET instead.


apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: test-get
  namespace: gloo-system
spec:
  virtualHost:
    domains:
      - 'foo'
    routes:
      - matchers:
         - methods:
            - GET
           prefix: /
        routeAction:
          single:
            upstream:
              name: json-upstream
              namespace: gloo-system
        options:
          autoHostRewrite: true

Because we removed the POST method matcher, sending a request using the POST method will now result in a 404 response from the Virtual Service. A GET request will successfully return a list of blog posts from the Upstream.

POST request:

curl -v -H "Host: foo" -XPOST $(glooctl proxy url)/posts

GET request:

curl -H "Host: foo" $(glooctl proxy url)/posts

Summary

In this guide, we created a virtual service that utilized HTTP method matching and demonstrated it on POST and GET requests.

Let’s cleanup the Virtual Service and Upstream we used.


kubectl delete vs -n gloo-system test-get
kubectl delete upstream -n gloo-system json-upstream

glooctl delete vs test-get
glooctl delete upstream json-upstream

Next Steps

HTTP method matching rules are not the only rules available for routing decisions. We recommend checking out any of the following guides next: