By extract HttpClient
inside Effect.Service
we defined a dependency to Api
on HttpClient
:
src/services/Api.ts
import { HttpClient, HttpClientRequest } from "@effect/platform";
import { Effect, flow } from "effect";
export class Api extends Effect.Service<Api>()("Api", {
effect: Effect.gen(function* () {
// 👇 Extracting a service creates a dependency
const baseClient = yield* HttpClient.HttpClient;
const client = baseClient.pipe(
HttpClient.mapRequest(
flow(
HttpClientRequest.prependUrl("https://jsonplaceholder.typicode.com"),
HttpClientRequest.acceptJson
)
)
);
return {
getPosts: client
.get("/posts")
.pipe(Effect.scoped),
getPostById: (id: string) =>
client
.get(`/posts/${id}`)
.pipe(Effect.scoped),
};
}),
}) {}
Executing Api
therefore requires a valid implementation of HttpClient
as a Layer
.
Learn more about
Layer
here: Building and composing layers
@effect/platform
already includes a Layer
for HttpClient
derived from fetch
called FetchHttpClient
.
FetchHttpClient
is a validHttpClient
implementation that usesfetch
to make requests.
We can directly provide FetchHttpClient
using dependencies
inside Effect.Service
:
src/services/Api.ts
import { FetchHttpClient, HttpClient, HttpClientRequest } from "@effect/platform";
import { Effect, flow } from "effect";
export class Api extends Effect.Service<Api>()("Api", {
dependencies: [FetchHttpClient.layer],
effect: Effect.gen(function* () {
const baseClient = yield* HttpClient.HttpClient;
const client = baseClient.pipe(
HttpClient.mapRequest(
flow(
HttpClientRequest.prependUrl("https://jsonplaceholder.typicode.com"),
HttpClientRequest.acceptJson
)
)
);
return {
getPosts: client
.get("/posts")
.pipe(Effect.scoped),
getPostById: (id: string) =>
client
.get(`/posts/${id}`)
.pipe(Effect.scoped),
};
}),
}) {}
With this we created the following dependency graph: Api
👉 HttpClient
(Api
depends on HttpClient
).