It's common practice to define a static Live
attribute inside a service class that exports a Layer
for the service.
Since make
is an Effect
we use Layer.effect
to create a layer from it:
const make = 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),
} as const;
});
export class Api extends Context.Tag("Api")<
Api,
Effect.Effect.Success<typeof make>
>() {
static readonly Live = Layer.effect(this, make);
}
Because inside make
we used HttpClient
, Live
has a dependency on it in its type: Layer<Api, never, HttpClient.HttpClient.Service>
.
We can directly provide a valid implementation of HttpClient
using Layer.provide
. @effect/platform
includes a HttpClient
derived from fetch
called FetchHttpClient
:
FetchHttpClient
is a validHttpClient
implementation that usesfetch
to make requests.
export class Api extends Context.Tag("Api")<
Api,
Effect.Effect.Success<typeof make>
>() {
static readonly Live = Layer.effect(this, make).pipe(
Layer.provide(FetchHttpClient.layer)
);
}
With this we created the following dependency graph: Api
👉 HttpClient
(Api
depends on HttpClient
).
In effect each dependency implementation is provided as a layer using Layer.provide
. Live
is now of type Layer<Api>
.