Example

OkHttp

Demonstrates how to call downstream services with helix-okhttp. Shows OAuth client credentials, outbound logging, metadata propagation, request ID propagation, retry, SLA, tracing, and downstream metrics inspected through the management actuator.
Group
REST API
Path
examples/rest-api/okhttp

Overview

Helix Spring Boot web service that shows how to call downstream HTTP services with helix-okhttp.

Run this example from the shared examples build:

Run

Run this example from the shared examples build


./gradlew -p examples runExample -Pexample=rest-api/okhttp --init-script "$(pwd)/helix.init.gradle"

What It Shows

  • the Helix API starter baseline
  • a purpose-built OkHttpClient created with helix-okhttp
  • OAuth client-credentials token refresh through ClientCredentialsOAuthInterceptor
  • outbound request and response logging through HelixHttpLoggingInterceptor
  • outbound metadata propagation through HelixMetadataInterceptor
  • outbound request ID propagation through RequestIdInterceptor
  • downstream retry behavior through RetryInterceptor
  • downstream SLA breach recording through ServiceLevelAgreementInterceptor
  • downstream tracing header propagation through DistributedTracingInterceptor
  • downstream request metrics through HelixHttpMetricsInterceptor
  • inspecting the downstream metrics through the management metrics actuator endpoint
  • local mock downstream services for the OAuth server and partner API

Endpoints

  • GET /v1/okhttp/orders/{orderId}
  • POST /mock/oauth/token
  • GET /mock/downstream/orders/{orderId}
  • GET /health
  • GET /liveness
  • GET /metrics/http.downstream.request.count
  • GET /metrics/http.downstream.request.success.count
  • GET /metrics/http.downstream.request.error.count

Example success response

{
  "orderId": "order-100",
  "channel": "partner",
  "partnerStatus": "FULFILLMENT_ACCEPTED",
  "authorizationScheme": "Bearer",
  "retryAttemptCount": 2,
  "downstreamRequestId": "okhttp-example-ecf5e4b7-8f91-43a0-9dce-318b87e6f7de",
  "propagatedMetadata": {
    "helix.metadata.capability": "orders",
    "helix.metadata.channel": "partner",
    "helix.metadata.orderId": "order-100"
  },
  "traceId": "4242424342",
  "spanId": "1515151520",
  "slaBreached": true,
  "slaDurationMs": 40,
  "downstreamRequestCount": 3.0,
  "downstreamSuccessCount": 1.0,
  "downstreamErrorCount": 2.0,
  "metricsUriTag": "/mock/downstream/orders/order-100"
}

Example outbound log line

{
  "message": "{\"type\":\"EXT-REQUEST\",\"method\":\"GET\",\"url\":\"http://localhost:8080/mock/downstream/orders/order-100?channel=partner\",\"headers\":{\"Authorization\":\"*****\",\"X-Request-ID\":\"ecf5e4b7-8f91-43a0-9dce-318b87e6f7de\",\"X-Metadata\":\"...\",\"x-datadog-trace-id\":\"4242424342\",\"x-datadog-parent-id\":\"1515151520\"}}"
}

Development

Building the Application

Run the following command to build the service:

Command

Building the Application


./gradlew clean build

Testing the Application

Run the following command to run the service tests:

Command

Testing the Application


./gradlew test
./gradlew integration

Trying the API

Run the service:

Then call the example endpoint:

What to look for in the API response:

  • the partner API accepted an OAuth bearer token - the downstream request ID shows the value propagated out of Helix context into the outbound request - Helix metadata values were encoded into X-Metadata and decoded again by the example - the retry count is 2 because the mock partner API fails once with 503 - the SLA flag is true because the successful downstream response is intentionally slow - the metric counts reflect the unauthenticated attempt, the retryable server error, and the final success

Inspect the downstream metrics through the actuator:

What to look for in the logs:

  • the outbound request log includes the propagated request ID, metadata header, and Datadog trace headers - the outbound request log redacts the OAuth Authorization header automatically - the outbound response log shows the retryable 503 and final 200 partner responses - the SLA recorder logs a warning when the slow downstream response exceeds the configured threshold

Command

Trying the API


./gradlew bootRun

Command

Trying the API


curl -i "http://localhost:8080/v1/okhttp/orders/order-100?channel=partner"

Command

Trying the API


curl "http://localhost:8081/metrics/http.downstream.request.count?tag=uri:/mock/downstream/orders/order-100"
curl "http://localhost:8081/metrics/http.downstream.request.success.count?tag=uri:/mock/downstream/orders/order-100"
curl "http://localhost:8081/metrics/http.downstream.request.error.count?tag=uri:/mock/downstream/orders/order-100"
curl "http://localhost:8081/metrics/http.downstream.request.error.count?tag=uri:/mock/downstream/orders/order-100&tag=type:client&tag=status:401"
curl "http://localhost:8081/metrics/http.downstream.request.error.count?tag=uri:/mock/downstream/orders/order-100&tag=type:server&tag=status:503"