java-graphql-dgs
1
总安装量
1
周安装量
#76254
全站排名
安装命令
npx skills add https://github.com/roelvandun/skills --skill java-graphql-dgs
Agent 安装分布
amp
1
cline
1
opencode
1
cursor
1
kimi-cli
1
codex
1
Skill 文档
Netflix DGS Framework Guide
DGS (Domain Graph Service) is a Netflix framework that makes it easy to build GraphQL services on top of Spring Boot. It uses an annotation-based programming model on top of Spring for GraphQL.
Process
Follow this process when adding or changing a GraphQL feature:
- Step 1: Define or update the schema in
src/main/resources/schema/*.graphqls - Step 2: Create or update a
@DgsComponentclass for the data fetcher - Step 3: Annotate the method with
@DgsQuery,@DgsMutation, or@DgsSubscription - Step 4: Use
@InputArgumentto bind query arguments - Step 5: Write a test using
@EnableDgsTestandDgsQueryExecutor
Quick Reference
Maven setup
See Setup for full dependency configuration.
The essential Maven addition (in dependencyManagement):
<dependency>
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-platform-dependencies</artifactId>
<version>10.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Plus the starter:
<dependency>
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>dgs-starter</artifactId>
</dependency>
Schema files
Place all GraphQL schema files in src/main/resources/schema/ with a .graphqls extension. DGS picks them up automatically.
type Query {
user(id: ID!): User
}
type User {
id: ID!
email: String!
name: String
}
Data fetcher
@DgsComponent
@RequiredArgsConstructor
public class UserDataFetcher {
private final UserService userService;
@DgsQuery
public User user(@InputArgument String id) {
return userService.findById(id);
}
}
Mutation
@DgsMutation
public User createUser(@InputArgument CreateUserInput input) {
return userService.create(input);
}
Use input CreateUserInput { ... } in the schema for mutation arguments.
Child data fetcher (avoid N+1)
When a field requires a separate query, use a child fetcher:
@DgsData(parentType = "User", field = "loyaltyCard")
public LoyaltyCard loyaltyCard(DgsDataFetchingEnvironment dfe) {
User user = dfe.getSource();
return cardService.findByCustomerId(user.getId());
}
For collections with N+1 concerns, see Data Fetchers.
Test
@SpringBootTest(classes = {UserDataFetcher.class, UserService.class})
@EnableDgsTest
class UserDataFetcherTest {
@Autowired
DgsQueryExecutor dgsQueryExecutor;
@Test
void user() {
String email = dgsQueryExecutor.executeAndExtractJsonPath(
"{ user(id: \"123\") { email } }",
"data.user.email"
);
assertThat(email).isEqualTo("test@example.com");
}
}
Reference Files
Core Topics
- Setup â Maven dependencies, module structure, application properties
- Data Fetchers â Annotations, arguments, child fetchers, data loaders
- Mutations â
@DgsMutation, input types, sparse updates - Data Loaders â
@DgsDataLoader,BatchLoader,MappedBatchLoader,Try, virtual threads - Subscriptions â
@DgsSubscription, WebSocket, SSE, testing - Error Handling â
@ControllerAdvice,TypedGraphQLError, subscription errors - Scalars â
@DgsScalar, extended scalars,@DgsRuntimeWiring - Code Generation â Gradle/Maven plugin, DgsConstants, type-safe query API
- Federation â
@key,@extends,@DgsEntityFetcher - Testing â
@EnableDgsTest,DgsQueryExecutor, MockMvc integration - Configuration â Full
dgs.graphql.*property reference - Spring GraphQL Integration â DGS/Spring GraphQL relationship, config overlap
Advanced Topics
- Context Passing â
getSource(),DataFetcherResult.localContext, selection set - Custom Datafetcher Context â
DgsCustomContextBuilder, per-request typed context - Custom Directives â
@DgsDirective,SchemaDirectiveWiring - Custom Object Mapper â Customizing Jackson for DGS deserialization
- Dynamic Schemas â
@DgsTypeDefinitionRegistry,@DgsCodeRegistry,ReloadSchemaIndicator - Federated Testing â Testing
_entitiesqueries - File Uploads â
scalar Upload,MultipartFile, multipart dependency - GraphQL Context â
GraphQLContextContributor, context in data loaders - Instrumentation â
SimplePerformantInstrumentation, Apollo Tracing - Intercepting HTTP â
WebGraphQlInterceptor, headers, response extensions - Java Client â
MonoGraphQLClient,GraphQLResponse, type-safe query API - Logging â
notprivacysafelogger, production settings - Operation Caching â
PreparsedDocumentProvider, Caffeine cache - Relay Pagination â
@connectiondirective,SimpleListConnection,PageInfo - Schema Reloading â Dev mode hot reload,
ReloadSchemaIndicator - Security â
@Secured,@PreAuthorize, Spring Security integration - Type Resolvers â
@DgsTypeResolverfor interfaces and unions - Virtual Threads â JDK 21+,
dgsAsyncTaskExecutor, test considerations
Key Rules
Schema design
- ALWAYS design schema first, then implement data fetchers
- ALWAYS place schema files in
src/main/resources/schema/with.graphqlsextension - ALWAYS use input types for mutation arguments:
mutation(input: MyInput!) - NEVER expose internal domain objects directly â create dedicated GraphQL types
Data fetchers
- ALWAYS annotate the data fetcher class with
@DgsComponent - USE
@DgsQuery/@DgsMutationas shorthands; use@DgsData(parentType, field)for child fetchers - USE
@InputArgumenton method parameters to bind GraphQL arguments - PREFER child fetchers with
DgsDataFetchingEnvironment.getSource()over embedding nested data in parent fetchers - ALWAYS use
@RequiredArgsConstructorwith Lombok for constructor injection
Testing
- ALWAYS test data fetchers with
@EnableDgsTestâ it is lighter than@SpringBootTestwith a full context - USE
DgsQueryExecutor.executeAndExtractJsonPath()to extract specific fields - USE
@MockBeanto mock service dependencies in data fetcher tests - NEVER rely on the HTTP layer in data fetcher unit tests â use
DgsQueryExecutorinstead
Ground Rules
- ALWAYS follow schema-first development: schema drives the Java implementation, not the other way around
- ALWAYS keep
@DgsComponentclasses free of business logic â delegate to@Serviceclasses - NEVER add DGS annotations to
@Serviceor@Repositoryclasses - PREFER the DGS programming model over Spring GraphQL annotations for consistency
- USE the platform BOM to manage DGS dependency versions â never pin individual module versions manually