@semyenov/effect-graphql
v0.1.2
Published
Build type-safe GraphQL schemas with Effect and Effect Schema. Type-safe resolvers, Effect integration, and batched loaders for relation fields.
Readme
@semyenov/effect-graphql
Build type-safe GraphQL schemas with Effect and Effect Schema. Type-safe resolvers, Effect integration, and batched loaders for relation fields.
Install
bun add @semyenov/effect-graphql effect graphqlQuickstart
import { Effect, Schema } from "effect";
import { createGraphApi } from "@semyenov/effect-graphql";
const draft = createGraphApi({ scope: "quickstart", serviceName: "quickstart-api" });
const AuthorBase = draft.object("Author", { id: Schema.String, name: Schema.String });
const QueryBase = draft.object("Query", {});
const objectMap = { Author: AuthorBase, Query: QueryBase } as const;
const builder = draft.withBuilder({ createContext: () => ({}), objectMap });
const Query = builder.contextual(QueryBase, (b) => ({
author: b.field({
type: builder.ref("Author"),
args: Schema.Struct({ id: Schema.String }),
resolve: (_src, args) => ({ id: args.id, name: "Alice" }),
}),
authorEffect: b.effect({
type: builder.ref("Author"),
args: Schema.Struct({ id: Schema.String }),
resolve: (_src, args) => Effect.succeed({ id: args.id, name: "Effect User" }),
}),
}));
const api = builder.defineRoots({ query: Query });
const schema = api.toSchema();To wire this into an HTTP server, see Server handlers. For Effect resolvers, pass runtimeProvider to api.toSchema(). For loader-backed relation fields with batching and caching, use builder.defineLoader (accepts either a batch or a resolver function) and see Resolvers — Loader-backed fields.
Documentation
- Documentation home
- Quickstart
- Core concepts
- Schema definition
- Resolvers
- Server handlers
- Errors and error policy
- Observability
- Configuration
- Examples
- API reference
- FAQ
Examples
See docs/examples.md for a consolidated guide to the examples.
Development
bun install
bun run test:all
bun run check