Rules engine
Real APIs misbehave: they omit headers you need, send cache directives that make no sense, expose fields you would rather redact, or expect vendor-specific quirks. HARP's rules engine lets you fix this at the proxy by running small Python scripts at well-defined points in a transaction's lifecycle, matching the requests and responses they apply to. You get fine-grained control over traffic without changing application code.
Transaction lifecycle
A transaction (a request and its response) triggers four events as it passes through the proxy. A rule attaches Python to one or more of these events to inspect or modify the exchange:
on_requestruns when the client request reaches the proxy, before routing.on_remote_requestruns just before the request is sent to the remote API.on_remote_responseruns when the remote response is received.on_responseruns on the final response, before it is returned to the client.
Pattern matching
Rules are written in TOML. Each rule is a table whose header combines an endpoint pattern with an HTTP method and path pattern, both supporting wildcards. The body assigns Python code to one or more lifecycle events:
[rules."*"."GET *"]
# Runs just before the request is sent to the remote API
on_remote_request = """
if not request.headers.get("Authorization"):
request.headers["Authorization"] = "Bearer ..."
"""
# Runs when the remote response is received
on_remote_response = """
response.headers["Cache-Control"] = "public, max-age=3600"
"""Python rules
Rules are plain Python, compiled to bytecode when the configuration is parsed. This validates their syntax at
startup and keeps execution efficient. Inside a rule you work with the request and response objects and a
logger, and you can answer a call immediately, without contacting the remote API, by producing an HttpResponse
(from harp.http import HttpResponse).
A single, unopinionated system
The engine makes no assumption about what a rule does, which keeps it open to a wide range of use cases. You can tune existing behaviour such as the HTTP cache, add new behaviour such as header injection, or set vendor-specific attributes consumed by your own code.
