import { ... } from "@effect/platform" // omitted to not make message too long for discord
import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
import { Context, Effect, Layer, Schema } from "effect"
import { createServer } from "node:http"
class User extends Schema.Class<User>("User")({ name: Schema.String }) {}
class Me extends Context.Tag("Me")<Me, User>() {}
class AuthenticationMiddleware extends HttpApiMiddleware.Tag<AuthenticationMiddleware>()(
"AuthenticationMiddleware",
{ provides: Me }
) {}
const AuthenticationMiddlewareLive = Layer.effect(
AuthenticationMiddleware,
Effect.gen(function*() {
// extract session from httponly cookie (omitted for simplicity)
return Effect.succeed(new User({ name: "alice" }))
})
)
const Api = HttpApi.make("api").add(
HttpApiGroup.make("greetings")
.add(HttpApiEndpoint.get("hello", "/hello").addSuccess(Schema.String))
).middleware(AuthenticationMiddleware)
const GreetingsLive = HttpApiBuilder.group(Api, "greetings", (handlers) =>
Effect.gen(function*() {
const me = yield* Me
return handlers.handle("hello", () => Effect.succeed(`hello ${me.name}`))
}))
// type of ApiLive: Layer.Layer<HttpApi.Api, never, Me> but I would expect it to be Layer.Layer<HttpApi.Api, never, never> since AuthenticationMiddlewareLive provides Me?
const ApiLive = HttpApiBuilder.api(Api).pipe(
Layer.provide(GreetingsLive),
Layer.provide(AuthenticationMiddlewareLive)
)
const Main = HttpApiBuilder.serve(HttpMiddleware.logger).pipe(
Layer.provide(ApiLive),
Layer.provide(NodeHttpServer.layer(createServer, { port: 4000 }))
)
NodeRuntime.runMain(Layer.launch(Main))
import { ... } from "@effect/platform" // omitted to not make message too long for discord
import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
import { Context, Effect, Layer, Schema } from "effect"
import { createServer } from "node:http"
class User extends Schema.Class<User>("User")({ name: Schema.String }) {}
class Me extends Context.Tag("Me")<Me, User>() {}
class AuthenticationMiddleware extends HttpApiMiddleware.Tag<AuthenticationMiddleware>()(
"AuthenticationMiddleware",
{ provides: Me }
) {}
const AuthenticationMiddlewareLive = Layer.effect(
AuthenticationMiddleware,
Effect.gen(function*() {
// extract session from httponly cookie (omitted for simplicity)
return Effect.succeed(new User({ name: "alice" }))
})
)
const Api = HttpApi.make("api").add(
HttpApiGroup.make("greetings")
.add(HttpApiEndpoint.get("hello", "/hello").addSuccess(Schema.String))
).middleware(AuthenticationMiddleware)
const GreetingsLive = HttpApiBuilder.group(Api, "greetings", (handlers) =>
Effect.gen(function*() {
const me = yield* Me
return handlers.handle("hello", () => Effect.succeed(`hello ${me.name}`))
}))
// type of ApiLive: Layer.Layer<HttpApi.Api, never, Me> but I would expect it to be Layer.Layer<HttpApi.Api, never, never> since AuthenticationMiddlewareLive provides Me?
const ApiLive = HttpApiBuilder.api(Api).pipe(
Layer.provide(GreetingsLive),
Layer.provide(AuthenticationMiddlewareLive)
)
const Main = HttpApiBuilder.serve(HttpMiddleware.logger).pipe(
Layer.provide(ApiLive),
Layer.provide(NodeHttpServer.layer(createServer, { port: 4000 }))
)
NodeRuntime.runMain(Layer.launch(Main))