As your API integration grows, you’ll find yourself adding the same headers, URL parameters, or other request modifications to every call. Instead of repeating that setup, you can bake it into the client using HttpClient.mapRequest().
mapRequest takes a function that modifies the request, and applies it to every outgoing request. The function is synchronous. It receives an HttpClientRequest and returns a new HttpClientRequest.
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.mapRequest( HttpClientRequest.prependUrl("https://dummyjson.com"), ), HttpClient.mapRequest( HttpClientRequest.setHeader("X-App-Version", "2.1.0"), ), );
// All requests now have the base URL and version header const response = yield* client.get("/products/1"); const product = yield* response.json;
return product; }).pipe(Effect.provide(FetchHttpClient.layer));}
// Test itEffect.runPromise(fetchFromApi()).then((product) => { console.log("Product:", product.title, `- $${product.price}`);});Output:
Product: Essence Mascara Lash Princess - $9.99In the example above, we create a client that automatically prepends a base URL and attaches a version header to every outgoing request. When we call client.get("/products/1"), the request is sent to https://dummyjson.com/products/1 with the X-App-Version header included, without repeating that setup on every request.
Each mapRequest call adds a transformation to the client. You can chain as many as you need, and they run in the order they’re registered. The first mapRequest prepends the base URL, and the second adds the header. Every request made through this client goes through both transformations.