Skip to content

Commit 39e0cd8

Browse files
authored
Maven plugin support for client code generation + example projects #37 (#62)
1 parent 7ab8cc8 commit 39e0cd8

File tree

45 files changed

+900
-210
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+900
-210
lines changed

.circleci/config.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ jobs:
6262
name: Build plugin and run unit tests
6363
command: cd ~/repo/plugins/maven/graphql-java-codegen-maven-plugin && mvn install
6464
- run:
65-
name: Build example plugin project
66-
command: cd ~/repo/plugins/maven/example && mvn package
65+
name: Build example-server plugin project
66+
command: cd ~/repo/plugins/maven/example-server && mvn package
67+
- run:
68+
name: Build example-client plugin project
69+
command: cd ~/repo/plugins/maven/example-client && mvn package
6770
build-graphql-java-codegen-gradle-plugin:
6871
description:
6972
Build gradle plugin
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>io.github.kobylynskyi</groupId>
6+
<artifactId>graphql-codegen-maven-plugin-example-client</artifactId>
7+
<version>1.6.0-SNAPSHOT</version>
8+
<name>graphql-codegen-maven-plugin-example-client</name>
9+
10+
<build>
11+
<plugins>
12+
<!-- GraphQL Codegen Maven plugin -->
13+
<plugin>
14+
<groupId>io.github.kobylynskyi</groupId>
15+
<artifactId>graphql-codegen-maven-plugin</artifactId>
16+
<version>${project.version}</version>
17+
<executions>
18+
<execution>
19+
<id>generate-sources-client</id>
20+
<goals>
21+
<goal>generate</goal>
22+
</goals>
23+
<configuration>
24+
<graphqlSchemaPaths>
25+
<graphqlSchemaPath>${project.basedir}/src/main/resources/external/schema-product-service.graphqls</graphqlSchemaPath>
26+
</graphqlSchemaPaths>
27+
<outputDir>${project.build.directory}/generated-sources/client</outputDir>
28+
<modelPackageName>io.github.kobylynskyi.product.graphql.model</modelPackageName>
29+
<customTypesMapping>
30+
<DateTime>java.util.Date</DateTime>
31+
</customTypesMapping>
32+
<modelNameSuffix>TO</modelNameSuffix>
33+
<generateRequests>true</generateRequests>
34+
<generateApis>false</generateApis>
35+
</configuration>
36+
</execution>
37+
<execution>
38+
<id>generate-sources-server</id>
39+
<goals>
40+
<goal>generate</goal>
41+
</goals>
42+
<configuration>
43+
<graphqlSchemaPaths>
44+
<graphqlSchemaPath>${project.basedir}/src/main/resources/schema.graphqls</graphqlSchemaPath>
45+
</graphqlSchemaPaths>
46+
<outputDir>${project.build.directory}/generated-sources/server</outputDir>
47+
<apiPackageName>io.github.kobylynskyi.order.graphql.api</apiPackageName>
48+
<modelPackageName>io.github.kobylynskyi.order.graphql.model</modelPackageName>
49+
<customTypesMapping>
50+
<DateTime>java.util.Date</DateTime>
51+
</customTypesMapping>
52+
<modelNameSuffix>TO</modelNameSuffix>
53+
</configuration>
54+
</execution>
55+
</executions>
56+
</plugin>
57+
<!-- GraphQL Codegen Maven plugin -->
58+
59+
<plugin>
60+
<groupId>org.apache.maven.plugins</groupId>
61+
<artifactId>maven-compiler-plugin</artifactId>
62+
<version>3.8.1</version>
63+
<configuration>
64+
<encoding>UTF-8</encoding>
65+
<source>1.8</source>
66+
<target>1.8</target>
67+
<showDeprecation>true</showDeprecation>
68+
<annotationProcessorPaths>
69+
<annotationProcessorPath>
70+
<groupId>org.projectlombok</groupId>
71+
<artifactId>lombok</artifactId>
72+
<version>1.18.8</version>
73+
</annotationProcessorPath>
74+
<annotationProcessorPath>
75+
<groupId>org.mapstruct</groupId>
76+
<artifactId>mapstruct-processor</artifactId>
77+
<version>1.3.0.Final</version>
78+
</annotationProcessorPath>
79+
</annotationProcessorPaths>
80+
</configuration>
81+
</plugin>
82+
</plugins>
83+
</build>
84+
85+
<dependencies>
86+
<dependency>
87+
<groupId>org.springframework.boot</groupId>
88+
<artifactId>spring-boot-starter-web</artifactId>
89+
<version>2.1.7.RELEASE</version>
90+
</dependency>
91+
<dependency>
92+
<groupId>org.springframework.boot</groupId>
93+
<artifactId>spring-boot-starter-data-mongodb</artifactId>
94+
<version>2.1.7.RELEASE</version>
95+
</dependency>
96+
<dependency>
97+
<groupId>org.springframework.data</groupId>
98+
<artifactId>spring-data-commons</artifactId>
99+
<version>2.1.10.RELEASE</version>
100+
</dependency>
101+
102+
<dependency>
103+
<groupId>com.graphql-java-kickstart</groupId>
104+
<artifactId>graphql-java-tools</artifactId>
105+
<version>5.6.1</version>
106+
</dependency>
107+
<dependency>
108+
<groupId>com.graphql-java-kickstart</groupId>
109+
<artifactId>graphql-spring-boot-starter</artifactId>
110+
<version>5.10.0</version>
111+
</dependency>
112+
<dependency>
113+
<groupId>com.graphql-java-kickstart</groupId>
114+
<artifactId>graphiql-spring-boot-starter</artifactId>
115+
<version>5.10.0</version>
116+
</dependency>
117+
118+
<dependency>
119+
<groupId>io.github.kobylynskyi</groupId>
120+
<artifactId>graphql-java-codegen</artifactId>
121+
<version>${project.version}</version>
122+
</dependency>
123+
<dependency>
124+
<groupId>org.apache.httpcomponents</groupId>
125+
<artifactId>httpclient</artifactId>
126+
<version>4.5.12</version>
127+
</dependency>
128+
129+
<dependency>
130+
<groupId>org.mapstruct</groupId>
131+
<artifactId>mapstruct</artifactId>
132+
<version>1.3.0.Final</version>
133+
</dependency>
134+
<dependency>
135+
<groupId>org.projectlombok</groupId>
136+
<artifactId>lombok</artifactId>
137+
<version>1.18.8</version>
138+
</dependency>
139+
</dependencies>
140+
141+
</project>

plugins/maven/example/src/main/java/io/github/kobylynskyi/bikeshop/Application.java renamed to plugins/maven/example-client/src/main/java/io/github/kobylynskyi/order/Application.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.kobylynskyi.bikeshop;
1+
package io.github.kobylynskyi.order;
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.github.kobylynskyi.order.external;
2+
3+
import io.github.kobylynskyi.order.model.Product;
4+
import io.github.kobylynskyi.product.graphql.model.ProductTO;
5+
import org.mapstruct.Mapper;
6+
7+
@Mapper(componentModel = "spring")
8+
public interface ExternalProductMapper {
9+
10+
Product map(ProductTO from);
11+
12+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package io.github.kobylynskyi.order.external;
2+
3+
import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequest;
4+
import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResult;
5+
import io.github.kobylynskyi.order.model.Product;
6+
import io.github.kobylynskyi.order.model.UnableToRetrieveProductException;
7+
import io.github.kobylynskyi.product.graphql.model.ProductByIdQueryRequest;
8+
import io.github.kobylynskyi.product.graphql.model.ProductResponseProjection;
9+
import io.github.kobylynskyi.product.graphql.model.ProductTO;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.beans.factory.annotation.Value;
12+
import org.springframework.core.ParameterizedTypeReference;
13+
import org.springframework.http.HttpEntity;
14+
import org.springframework.http.HttpHeaders;
15+
import org.springframework.http.HttpMethod;
16+
import org.springframework.http.MediaType;
17+
import org.springframework.stereotype.Service;
18+
import org.springframework.web.client.RestTemplate;
19+
20+
import java.net.URI;
21+
import java.util.Collections;
22+
import java.util.Map;
23+
24+
@Service
25+
public class ProductServiceGraphQLClient {
26+
27+
@Autowired
28+
private ExternalProductMapper productMapper;
29+
30+
@Autowired
31+
private RestTemplate restTemplate;
32+
33+
@Value("${external.service.product.url}")
34+
private String productUrl;
35+
36+
public Product getProduct(String productId) throws UnableToRetrieveProductException {
37+
ProductByIdQueryRequest getProductRequest = new ProductByIdQueryRequest();
38+
getProductRequest.setId(productId);
39+
GraphQLRequest request = new GraphQLRequest(getProductRequest,
40+
new ProductResponseProjection()
41+
.id()
42+
.title()
43+
.price());
44+
45+
GraphQLResult<Map<String, ProductTO>> result = restTemplate.exchange(URI.create(productUrl),
46+
HttpMethod.POST,
47+
httpEntity(request),
48+
new ParameterizedTypeReference<GraphQLResult<Map<String, ProductTO>>>() {
49+
}).getBody();
50+
assert result != null;
51+
if (result.hasErrors()) {
52+
throw new UnableToRetrieveProductException(productId, result.getErrors().get(0).getMessage());
53+
}
54+
return productMapper.map(result.getData().get(getProductRequest.getOperationName()));
55+
}
56+
57+
private static HttpEntity<String> httpEntity(Object request) {
58+
HttpHeaders headers = new HttpHeaders();
59+
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
60+
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
61+
return new HttpEntity<>(request.toString(), headers);
62+
}
63+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.github.kobylynskyi.order.external.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
6+
import org.springframework.web.client.RestTemplate;
7+
8+
@Configuration
9+
public class RestClientsConfiguration {
10+
11+
@Bean
12+
public RestTemplate restTemplate() {
13+
return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
14+
}
15+
16+
}

plugins/maven/example/src/main/java/io/github/kobylynskyi/bikeshop/graphql/GraphQLController.java renamed to plugins/maven/example-client/src/main/java/io/github/kobylynskyi/order/graphql/GraphQLController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.kobylynskyi.bikeshop.graphql;
1+
package io.github.kobylynskyi.order.graphql;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
44
import graphql.ExecutionInput;

plugins/maven/example/src/main/java/io/github/kobylynskyi/bikeshop/graphql/config/GraphQLConfiguration.java renamed to plugins/maven/example-client/src/main/java/io/github/kobylynskyi/order/graphql/config/GraphQLConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.kobylynskyi.bikeshop.graphql.config;
1+
package io.github.kobylynskyi.order.graphql.config;
22

33
import graphql.GraphQL;
44
import graphql.execution.AsyncExecutionStrategy;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.kobylynskyi.order.graphql.mappers;
2+
3+
import io.github.kobylynskyi.order.graphql.model.ItemTO;
4+
import io.github.kobylynskyi.order.graphql.model.OrderTO;
5+
import io.github.kobylynskyi.order.model.Item;
6+
import io.github.kobylynskyi.order.model.Order;
7+
import org.mapstruct.Mapper;
8+
import org.mapstruct.Mapping;
9+
10+
@Mapper(componentModel = "spring")
11+
public interface OrderMapper {
12+
13+
OrderTO map(Order from);
14+
15+
ItemTO map(Item from);
16+
17+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.github.kobylynskyi.order.graphql.resolvers;
2+
3+
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
4+
import io.github.kobylynskyi.order.graphql.api.Mutation;
5+
import io.github.kobylynskyi.order.graphql.mappers.OrderMapper;
6+
import io.github.kobylynskyi.order.graphql.model.OrderTO;
7+
import io.github.kobylynskyi.order.service.OrderService;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
public class MutationsResolver implements Mutation, GraphQLMutationResolver {
13+
14+
@Autowired
15+
private OrderService service;
16+
@Autowired
17+
private OrderMapper mapper;
18+
19+
@Override
20+
public OrderTO create() {
21+
return mapper.map(service.create());
22+
}
23+
24+
@Override
25+
public OrderTO addProductToOrder(String orderId, String productId, Integer quantity) throws Exception {
26+
return mapper.map(service.addProduct(orderId, productId, quantity));
27+
}
28+
}

0 commit comments

Comments
 (0)