Update response body

Learn how to return a customized response body and how replace specific values in the body.

In this guide, you use the following methods to transform a JSON body:

  • Directly access fields in the JSON body and inject them into a custom JSON body.
  • Use the replace_with_random Inja function to replace specific patterns in the JSON body.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. Get the external address of the gateway and save it in an environment variable.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS  
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

Update response body

  1. Send a request to the json endpoint of the httpbin app. The request returns a JSON body that you later transform.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/json \
     -H "host: www.example.com:8080" 
    curl -vi localhost:8080/json \
    -H "host: www.example.com"

    Example output:

    {
      "slideshow": {
        "author": "Yours Truly",
        "date": "date of publication",
       "slides": [
          {
            "title": "Wake up to WonderWidgets!",
            "type": "all"
          },
          {
            "items": [
              "Why <em>WonderWidgets</em> are great",
              "Who <em>buys</em> WonderWidgets"
            ],
            "title": "Overview",
            "type": "all"
          }
        ],
        "title": "Sample Slide Show"
      }
    }
    
  2. Create a TrafficPolicy resource with your transformation rules:

    • A new body is created in the response with the values of the author, title, and slides fields.
    • To extract the values, you use dot notation. Because the response is parsed as a JSON file, no extractors need to be defined. Instead, you can access the fields directly.
    kubectl apply -f- <<EOF
    apiVersion: gateway.kgateway.dev/v1alpha1
    kind: TrafficPolicy
    metadata:
      name: transformation
      namespace: httpbin
    spec:
      transformation:
        response:
          body: 
            parseAs: AsJson
            value: '{"author": "{{ slideshow.author }}", "title": "{{ slideshow.title }}", "slides": "{{ slideshow.slides }}}'
    EOF
  3. Update the HTTPRoute resource to apply the TrafficPolicy to the httpbin route by using an extensionRef filter.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
      namespace: httpbin
      labels:
        example: httpbin-route
    spec:
      parentRefs:
        - name: http
          namespace: kgateway-system
      hostnames:
        - "www.example.com"
      rules:
        - backendRefs:
            - name: httpbin
              port: 8000
          filters:
          - type: ExtensionRef
            extensionRef:
              group: gateway.kgateway.dev
              kind: TrafficPolicy
              name: transformation
    EOF
  4. Send a request to the json endpoint of the httpbin app again. Verify that you see the transformed response body.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/json \
     -H "host: www.example.com:8080" 
    curl -vi localhost:8080/json \
    -H "host: www.example.com"

    Example output:

    {"author": "Yours Truly", "title": "Sample Slide Show", "slides":
    "[{"title":"Wake up to WonderWidgets!","type":"all"},{"items":
    ["Why <em>WonderWidgets</em> are great","Who <em>buys</em> WonderWidgets"],
    "title":"Overview","type":"all"}]}
    
  5. Update the TrafficPolicy resource to replace the all pattern with a random string.

    kubectl apply -f- <<EOF
    apiVersion: gateway.kgateway.dev/v1alpha1
    kind: TrafficPolicy
    metadata:
      name: transformation
      namespace: httpbin
    spec:
      transformation:
        response:
          body: 
            parseAs: AsJson
            value: '{{ replace_with_random(body(), "all") }}'
    EOF
  6. Send another request to the json endpoint of the httpbin app. Verify that every all value is replaced with a random string.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/json \
     -H "host: www.example.com:8080" 
    curl -vi localhost:8080/json \
    -H "host: www.example.com"

    Example output:

    {
      "slideshow": {
        "author": "Yours Truly",
        "date": "date of publication",
        "slides": [
          {
            "title": "Wake up to WonderWidgets!",
            "type": "5pESMzYNtg8W9AG/eVZ13A"
          },
          {
            "items": [
              "Why <em>WonderWidgets</em> are great",
              "Who <em>buys</em> WonderWidgets"
            ],
            "title": "Overview",
            "type": "5pESMzYNtg8W9AG/eVZ13A"
          }
        ],
        "title": "Sample Slide Show"
      }
    }
    

Cleanup

You can remove the resources that you created in this guide.
  1. Delete the TrafficPolicy resource.

    kubectl delete TrafficPolicy transformation -n httpbin
  2. Remove the extensionRef filter from the HTTPRoute resource.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
      namespace: httpbin
      labels:
        example: httpbin-route
    spec:
      parentRefs:
        - name: http
          namespace: kgateway-system
      hostnames:
        - "www.example.com"
      rules:
        - backendRefs:
            - name: httpbin
              port: 8000
    EOF