
Security News
GitHub Actions Checkout Now Blocks Risky pull_request_target Checkouts
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.
@fluojs/graphql
Advanced tools
Decorator-based GraphQL module, schema exposure, and execution pipeline for Fluo.
English 한국어
Decorator-based GraphQL integration for fluo. Built on GraphQL Yoga, it provides a high-performance, specification-compliant GraphQL execution pipeline with deep DI integration and first-party DataLoader support.
pnpm add @fluojs/graphql graphql graphql-yoga
GraphQLSchema object into a fluo application.Register GraphqlModule.forRoot(...) and define a resolver using standard decorators. @fluojs/graphql currently exposes a synchronous module entrypoint only; there is no GraphqlModule.forRootAsync(...) contract.
You can also pass an executable GraphQLSchema via schema when you want schema-first integration instead of code-first resolver discovery.
import { Module } from '@fluojs/core';
import { bootstrapNodeApplication } from '@fluojs/runtime/node';
import { GraphqlModule, Query, Resolver, Arg } from '@fluojs/graphql';
class HelloInput {
@Arg('name')
name = '';
}
@Resolver()
class HelloResolver {
@Query({ input: HelloInput })
hello(input: HelloInput): string {
return `Hello, ${input.name}!`;
}
}
@Module({
imports: [
GraphqlModule.forRoot({
resolvers: [HelloResolver]
})
],
providers: [HelloResolver]
})
class AppModule {}
const app = await bootstrapNodeApplication(AppModule);
await app.listen(3000);
// curl -X POST http://localhost:3000/graphql \
// -H "Content-Type: application/json" \
// -d '{"query": "{ hello(name: \"fluo\") }"}'
fluo uses standard decorators to define your GraphQL schema. Use @Resolver, @Query, @Mutation, and @Subscription to map class methods to GraphQL operations. GraphQL arguments are declared on input DTO fields with @Arg(...), then passed to the resolver method through the operation input option.
@fluojs/graphql currently supports root operation resolvers only. Object field-resolver patterns such as author(book, context) remain design-only and are documented in packages/graphql/field-resolver-rfc.md, not in the runtime contract.
Efficiently solve the N+1 problem with built-in DataLoader integration. Loaders are automatically isolated per GraphQL operation.
import { createDataLoader, type GraphQLContext } from '@fluojs/graphql';
const userLoader = createDataLoader(async (ids: string[]) => {
const users = await userService.findByIds(ids);
return ids.map(id => users.find(u => u.id === id));
});
class UserInput {
@Arg('id')
id = '';
}
@Resolver()
class UserResolver {
@Query({ input: UserInput })
async user(input: UserInput, context: GraphQLContext) {
return userLoader(context).load(input.id);
}
}
@Scope('request'); this keeps DI lifetime rules explicit and avoids singleton-to-request dependency mismatches.@fluojs/graphql creates one operation-scoped DI container for each HTTP GraphQL request or websocket subscription operation, shares it across resolver calls in that operation, and disposes it when the operation completes or the websocket operation disconnects.GraphQLContext whose built-in fields expose the underlying fluo request, the authenticated HTTP principal when middleware or guards set one, websocket connectionParams and socket for websocket subscriptions, and any custom fields returned from GraphqlModule.forRoot({ context }).GraphQLContext operation boundary, so loader caches are shared only within one GraphQL operation.import { Inject, Scope } from '@fluojs/core';
import { Query, Resolver } from '@fluojs/graphql';
@Scope('request')
class RequestState {
private static nextId = 0;
readonly requestId = `request-${++RequestState.nextId}`;
}
@Inject(RequestState)
@Scope('request')
@Resolver()
class RequestResolver {
constructor(private readonly state: RequestState) {}
@Query('requestId')
requestId(): string {
return this.state.requestId;
}
}
graphql-ws support for real-time subscriptions when the active adapter exposes a Node HTTP/S server with upgrade listeners (for example, the Node HTTP adapter).HTTP queries/mutations and the default SSE subscription path run through fluo's portable HTTP abstraction. The optional websocket transport is intentionally narrower: it requires a server-backed Node HTTP/S adapter surface, so Bun, Deno, and Cloudflare Workers deployments should keep the default SSE path unless their adapter exposes compatible upgrade listeners.
GraphqlModule.forRoot({
subscriptions: {
websocket: {
enabled: true,
limits: {
maxConnections: 100,
maxPayloadBytes: 64 * 1024,
maxOperationsPerConnection: 25,
},
}
}
})
@Subscription({ topics }) is not supported. Subscription resolvers must return an AsyncIterable.
graphiql or set introspection: true.graphiql defaults to false. introspection follows graphiql unless set explicitly, so production apps stay private by default while local GraphiQL sessions can opt in.limits accepts request validation budgets or false; use false only when equivalent controls exist outside fluo.graphql/jsutils/instanceOf patch before rethrowing, so failed startups do not leak process-wide GraphQL behavior into later app attempts.100 concurrent connections, 64 KiB maximum payload size, and 25 active operations per connection.subscriptions.websocket.enabled defaults to false; enabling it requires a Node HTTP/S adapter with upgrade support. connectionInitWaitTimeoutMs is forwarded to graphql-ws for connection initialization, and keepAliveMs controls websocket keepalive pings when configured.subscriptions.websocket.limits = false only when you intentionally need unbounded websocket behavior and can enforce equivalent controls elsewhere.limits: false only when you intentionally need unbounded behavior and can compensate with external controls.GraphqlModule.forRoot({
graphiql: false,
introspection: false,
limits: {
maxDepth: 8,
maxComplexity: 120,
maxCost: 240,
},
subscriptions: {
websocket: {
enabled: true,
limits: {
maxConnections: 100,
maxPayloadBytes: 64 * 1024,
maxOperationsPerConnection: 25,
},
},
},
resolvers: [HelloResolver],
})
GraphqlModule.forRoot(options): Main entry point for GraphQL integration.Resolver, Query, Mutation, Subscription: Operation decorators.Arg: Input DTO field-to-GraphQL-argument mapping decorator.createDataLoader, createDataLoaderMap, getRequestScopedDataLoader, createRequestScopedDataLoaderFactory, DataLoader: DataLoader factory helpers and types.listOf, isGraphqlListTypeRef: Helpers for list output type references.GraphQLContext and exported option/metadata types: Type definitions for GraphQL execution and module configuration.Supported module options include schema, context, plugins, graphiql, introspection, limits, subscriptions.websocket.enabled, subscriptions.websocket.limits, subscriptions.websocket.connectionInitWaitTimeoutMs, and subscriptions.websocket.keepAliveMs.
@fluojs/core: Core DI and module system.@fluojs/http: Underlying HTTP abstraction.@fluojs/validation: Integrated DTO validation for GraphQL inputs.packages/graphql/src/module.test.ts: Integration tests and usage examples for module registration, resolver execution, request-scoped containers, subscriptions, and guardrail defaults.packages/graphql/field-resolver-rfc.md: Design notes for field-resolver patterns that are not part of the current runtime contract.FAQs
Decorator-based GraphQL module, schema exposure, and execution pipeline for Fluo.
The npm package @fluojs/graphql receives a total of 24 weekly downloads. As such, @fluojs/graphql popularity was classified as not popular.
We found that @fluojs/graphql demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.