项目地址 Github: dongfg/api
依赖 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <dependency > <groupId > com.graphql-java</groupId > <artifactId > graphql-spring-boot-starter</artifactId > <version > LATEST</version > </dependency > <dependency > <groupId > com.graphql-java</groupId > <artifactId > graphiql-spring-boot-starter</artifactId > <version > LATEST</version > </dependency > <dependency > <groupId > com.graphql-java</groupId > <artifactId > graphql-java-tools</artifactId > <version > LATEST</version > </dependency >
配置过程简单分析
GraphQLWebAutoConfiguration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Autowired(required = false) private List<GraphQLServletListener> listeners;@Autowired(required = false) private Instrumentation instrumentation;@Autowired(required = false) private GraphQLErrorHandler errorHandler;@Autowired(required = false) private Map<String, ExecutionStrategy> executionStrategies;@Autowired(required = false) private GraphQLContextBuilder contextBuilder;@Autowired(required = false) private GraphQLRootObjectBuilder graphQLRootObjectBuilder;@Autowired(required = false) private ObjectMapperConfigurer objectMapperConfigurer;... @Bean @ConditionalOnMissingBean public GraphQLServlet graphQLServlet (GraphQLSchemaProvider schemaProvider, ExecutionStrategyProvider executionStrategyProvider) { return new SimpleGraphQLServlet(schemaProvider, executionStrategyProvider, objectMapperConfigurer, listeners, instrumentation, errorHandler, contextBuilder, graphQLRootObjectBuilder); } ...
GraphiQLAutoConfiguration
1 2 3 4 5 6 @Bean @ConditionalOnProperty(value = "graphiql.enabled", havingValue = "true", matchIfMissing = true) GraphiQLController graphiQLController () { return new GraphiQLController(); }
GraphQLJavaToolsAutoConfiguration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 @Autowired(required = false) private SchemaParserDictionary dictionary;@Autowired(required = false) private GraphQLScalarType[] scalars;@Autowired(required = false) private SchemaParserOptions options;@Autowired private ApplicationContext applicationContext;@Bean @ConditionalOnBean({GraphQLResolver.class}) @ConditionalOnMissingBean public SchemaParser schemaParser (List<GraphQLResolver<?>> resolvers) throws IOException { SchemaParserBuilder builder = dictionary != null ? new SchemaParserBuilder(dictionary) : new SchemaParserBuilder(); Resource[] resources = applicationContext.getResources("classpath*:**/*.graphqls" ); if (resources.length <= 0 ) { throw new IllegalStateException("No *.graphqls files found on classpath. Please add a graphql schema to the classpath or add a SchemaParser bean to your application context." ); } for (Resource resource : resources) { StringWriter writer = new StringWriter(); IOUtils.copy(resource.getInputStream(), writer); builder.schemaString(writer.toString()); } if (scalars != null ) { builder.scalars(scalars); } if (options != null ) { builder.options(options); } return builder.resolvers(resolvers) .build(); } @Bean @ConditionalOnBean(SchemaParser.class) @ConditionalOnMissingBean({GraphQLSchema.class, GraphQLSchemaProvider.class}) public GraphQLSchema graphQLSchema (SchemaParser schemaParser) { return schemaParser.makeExecutableSchema(); }
关于工程化 按照MVC的设计方法,resolver相当于controller层
关于模块化 schema 模块化 classpath 下所有 schema 文件都会加载,利用 extend type
的 feature 可以实现简单的模块化划分
1 2 3 4 resources/graphqls ├── common.graphqls ├── mongo.graphqls └── ssl.graphqls
common.graphqls
1 2 3 type Query { version: String! }
mongo.graphqls
1 2 3 4 extend type Query { collectionNames: [String] collectionData(collectionName: String!): [String] }
Resolver 模块化 FieldResolverScanner会在GraphQLQueryResolver所有实现类方法中查找schema的query
1 2 3 4 query ├── CommonQueryResolver.java ├── MongoQueryResolver.java └── SSLQueryResolver.java