Argo Workflows can make HTTP requests to external services, which is incredibly useful for integrating with APIs, triggering other systems, or even just checking the health of a service.
Let’s see this in action. Imagine you have a workflow that needs to get some data from an API and then use that data in a subsequent step.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: http-example-
spec:
entrypoint: main
templates:
- name: main
dag:
tasks:
- name: get-data
template: http-get
- name: process-data
template: http-post
dependencies: [get-data]
- name: http-get
http:
url: http://example.com/api/data
method: GET
successCondition: status_code == 200
headers:
- name: Accept
value: application/json
- name: Authorization
value: Bearer my-secret-token
- name: X-Argo-Workflow
value: "{{workflow.name}}"
# The response body is captured and can be used by downstream steps
# For example, in a script template:
# - name: process-data
# script:
# command: [python]
# source: |
# import json
# data = json.loads("{{tasks.get-data.outputs.result}}")
# print(f"Received data: {data}")
- name: http-post
http:
url: http://example.com/api/process
method: POST
successCondition: status_code == 201
contentType: application/json
body: |
{
"message": "Processing data from Argo",
"workflow_id": "{{workflow.uid}}",
"input_data": "{{tasks.get-data.outputs.result}}"
}
This workflow defines two tasks: get-data which makes a GET request, and process-data which makes a POST request. The get-data task uses the http template type, specifying the url, method, and a successCondition to determine if the request was successful. It also shows how to include headers.
The process-data task, which depends on get-data completing, uses the http template type again but with a POST method. It demonstrates setting contentType and sending a body. Crucially, the body references the output of the get-data task using {{tasks.get-data.outputs.result}}. This result field automatically captures the response body from the HTTP request.
Internally, Argo Workflows uses a dedicated controller that manages these HTTP requests. When a step with an http template is executed, Argo sends the request to the specified URL. It then evaluates the successCondition against the response. If the condition is met, the step is considered successful, and its output (the response body) is made available to subsequent steps. If the condition is not met, or if there’s a network error, the step fails.
You can also use environment variables or secrets for sensitive information like tokens. For instance, to pass a token from a Kubernetes Secret named my-api-secret with a key token, you’d modify the http-get template:
- name: http-get
http:
url: http://example.com/api/data
method: GET
successCondition: status_code == 200
headers:
- name: Authorization
value: "{{=lookup 'secret' 'my-api-secret' 'token'}}"
Here, {{=lookup 'secret' 'my-api-secret' 'token'}} dynamically fetches the token from the Kubernetes Secret.
The successCondition is powerful. It allows you to define what constitutes a successful HTTP response beyond just a 2xx status code. For example, you could check for specific values in the response body: successCondition: status_code == 200 && response.body.status == "completed". The response object within the condition has access to status_code, body, and headers.
The most surprising thing most users don’t realize is that the successCondition can also directly reference the response object’s fields, not just the status_code. This means you can have a step succeed or fail based on the content of the HTTP response, making your workflows much more dynamic and responsive to API feedback. For example, successCondition: status_code == 200 && response.body.data.items.length > 0 would only succeed if the status code is 200 AND the response body (parsed as JSON) contains an array named items with at least one element.
The next concept you’ll likely explore is how to handle more complex error scenarios, such as retrying failed HTTP requests or implementing custom error handling logic based on specific response codes.