Transforming Responses

Avatar of Hemanta SundarayHemanta Sundaray

Just as you can transform outgoing requests, you can also transform the response pipeline. HttpClient.transformResponse() wraps the response effect itself, letting you apply Effect combinators to every response.

This is useful for cross-cutting response concerns: adding timeouts, retries, or caching behavior to every request made through a client.

http.ts
import {
FetchHttpClient,
HttpClient,
HttpClientRequest,
} from "effect/unstable/http";
import { Effect } from "effect";
function fetchFromApi() {
return Effect.gen(function* () {
const client = (yield* HttpClient.HttpClient).pipe(
HttpClient.transformResponse((responseEffect) =>
responseEffect.pipe(
Effect.tap((response) =>
Effect.log(`Response received: ${response.status}`),
),
Effect.timeout("10 seconds"),
),
),
);
const response = yield* client.get("https://dummyjson.com/users/1");
const user = yield* response.json;
return user;
}).pipe(Effect.provide(FetchHttpClient.layer));
}
// Test it
Effect.runPromise(fetchFromApi()).then((user) => {
console.log("User:", user.firstName, user.lastName);
});

Output:

Terminal
[12:47:43.151] INFO (#2): Response received: 200
User: Emily Johnson

The function passed to transformResponse receives the full Effect<HttpClientResponse, E, R>, not just the response, but the effect that produces it. This means you can wrap it with any Effect combinator: timeout, retry, tap, catchAll, and so on.

Because transformResponse replaces the entire response pipeline, any errors or requirements introduced by your transform (like a TimeoutException from Effect.timeout) become part of the client’s error type.

Sign in to save progress

Stay in the loop

Get notified when new chapters are added and when this course is complete.