FLAT
CouperSevenval TechnologiesDocker ImageGithub
master
master
  • Changelog
  • FLAT
  • Administration
    • Configuration
    • Docker
    • Logging
  • Cookbook
    • Using the Built-in Mocking
    • Performing Additional Checks on JWT Access Tokens
    • Logging Custom Fields
    • Using Environment Variables
    • Handling Errors with an Error Flow
    • File Serving
    • Forwarding a Request to an Upstream API
    • Extracting Common Initialization Flow Tasks
    • Encoding and Decoding JWT
    • Passing Header Fields to the Client
    • How can I pass an arbitrary header field to an upstream system?
    • Performing Additional Checks on JWT Access Tokens
    • Proxying requests to Upstream APIs
    • Increasing the Request Timeout
    • How can I see what the client requested?
    • Using Swagger UI for API Documentation
    • Testing API Requests
    • Testing with Backend Requests
    • Testing Templates
    • Sending POST Requests
    • Processing Upstream Responses
    • Protecting Access using JWT Tokens
  • Reference
    • Configuration
    • Debugging
    • flat CLI
    • Flow
    • Variables
    • OpenAPI / Swagger Integration
    • OpenAPI
      • CORS - Cross-Origin Resource Sharing
    • OpenAPI
      • Differences from Swagger
    • OpenAPI
      • Mocking
    • OpenAPI
      • Routing
    • OpenAPI
      • Security
    • OpenAPI
      • Upstream APIs
    • OpenAPI
      • Validation
    • Flow Actions
      • assert Action
      • auth Action
      • backend-flow Action
      • copy Action
      • debug Action
      • dump Action
      • echo Action
      • error Action
      • eval Action
      • log Action
      • nameshave Action
      • pass-body Action
      • proxy-request Action
      • regex Action
      • request Action
      • requests Action
      • serve Action
      • set-config Action
      • set-env Action
      • set-response-headers Action
      • set-status Action
      • sub-flow Action
      • template Action
      • test-request Action
      • xslt Action
    • Functions
      • apply-codecs()
      • array-reverse()
      • array()
      • base64-decode()
      • base64-encode()
      • body()
      • calc-signature()
      • capitalize-first()
      • content()
      • decrypt-xml()
      • decrypt()
      • encrypt()
      • ends-with()
      • file-exists()
      • fit-document()
      • fit-log()
      • fit-serialize()
      • get-log()
      • has-class()
      • html-parse()
      • join()
      • json-doc()
      • json-parse()
      • json-stringify()
      • json-to-csv()
      • json-to-xml()
      • jwt-decode()
      • jwt-encode()
      • ldap-lookup()
      • ldap-query()
      • lookup()
      • matches()
      • md5()
      • replace()
      • sort()
      • split()
      • tolower()
      • toupper()
      • trim()
      • unixtime()
      • urldecode(), url-decode()
      • urlencode(), url-encode()
      • uuid3() and uuid4()
      • verify-signature()
      • verify-xmldsig()
      • xml-parse()
      • xml-to-json()
    • Templating
      • {{,}}
      • Comment {{// …}}
      • Dot {{.}}
      • Conditional `{{if <condition>}} … {{elseif <condition> }} … {{else}} … {{end}}
      • loop
      • ?? Operator
      • Object XML Notation (OXN)
      • Pair Producer {{: …}}
      • Placeholder
      • Template Variables
      • with
    • Testing
  • Tutorial
Powered by GitBook
On this page

Was this helpful?

  1. Cookbook

Forwarding a Request to an Upstream API

PreviousFile ServingNextExtracting Common Initialization Flow Tasks

Last updated 5 years ago

Was this helpful?

To forward a request to an upstream API ("proxy" a request), you can simply use a , for example

<flow>
  <proxy-request>
  {
    "url": "https://httpbin.org/anything"
  }
  </proxy-request>
</flow>

to delegate the incoming request to .

The following shows a more advanced example:

<flow>
  <proxy-request>
  {
    {{// Replace the origin of the incoming request with the UPSTREAM_ORIGIN environment variable }}
    "origin": {{ $env/UPSTREAM_ORIGIN }},

    "headers": {
      {{// Set X-tra, drop X-Remove, copy Authorization }}
      "X-tra": "42",
      "X-Remove": "" {{,}}
      {{: $request/headers/authorization }}
    },

    "options": {
      "timeout": "exit-on-error": true,
      "validate-request": true,
      …
    }
  }
  </proxy-request>
</flow>

The proxy-request action lets you set the origin and modify the headers of the request. Everything else is set up automatically: The client request body will be forwarded as-is, any headers not intended for upstream will be dropped.

<flow>
  <request>
  {
    {{// the URL for the upstream API}}
    "url": {{ replace($request/url, "^http://[^/]+", $env/UPSTREAM_URI) }},

    {{// copy the request method and query }}
    {{: $request/method | $request/query }},

    {{// set the request body}}
    "body": {
      "src": "$body"
    },
    {{// if set, copy specific headers, here foo and bar }}
    "headers": {
      {{: $request/headers/foo | $request/headers/bar }}
    },
    {{// if set, copy specific cookies, here SessionID and quux }}
    "cookies": {
      {{: $request/cookies/SessionID | $request/cookies/quux }}
    }
  }
  </request>

  <set-response-headers>
  {
    {{// pass through the upstream response status (defaults to 200) }}
    "status": {{ $upstream/main/status }}{{,}}
    {{// forward certain upstream response header fields }}
    {{: $upstream/main/headers/cache-control | $upstream/main/headers/set-cookie }}
  }
  </set-response-headers>
</flow>

Since we are implicitly using the default request ID main in the above example, the body together with its Content-Type is automatically set as the response body to be sent to the client.

The forwarded request will only have a body if the incoming request does. The Content-Type request and response headers are passed automatically with the body, therefore we don't have to copy them explicitly.

If the client and the upstream request URL paths do not share a common prefix, you can easily adjust the path by using stripEndpoint and addPrefix:

{
  "origin": {{ $env/UPSTREAM_ORIGIN }},
  "stripEndpoint: true,
  "addPrefix": {{ $env/UPSTREAM_PATH_PREFIX }},
  …
}

Assuming the following swagger.yaml for https://client.example.com/

basePath: /api
paths:
  /users/**:
    …

, https://users.upstream.example.com for UPSTREAM_ORIGIN, and /v4 for UPSTREAM_PATH_PREFIX, a client request for https://client.example.com/api/users/profile will be forwarded to https://users.upstream.example.com/v4/profile.

See also

If you need to further modify the request, you'll have to configure a that forwards the incoming request with your modifications upstream. This gives you full control over the upstream request, but there's quite much thinking involved to get this fully right.

The following example illustrates, how such a request could look like. We just modify the url, copy method and query using and set the request body by referencing the :

The ensures that the HTTP status code of the upstream response and possibly additional header fields are correctly forwarded to the client.

(cookbook)

(reference)

(reference)

proxy-request action
httpbin.org
flow
request action
set-response-headers action
Proxying requests to Upstream APIs
proxy-request action
request action
pair producers
$body variable