Skip to content

Commit 47d40aa

Browse files
author
ext_zhongling
committed
feat: Spring Boot整合 GraphQL新式API风格项目案例
1 parent 3f170ea commit 47d40aa

File tree

11 files changed

+536
-0
lines changed

11 files changed

+536
-0
lines changed

springboot-graphql/.gitignore

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
HELP.md
2+
target/
3+
!.mvn/wrapper/maven-wrapper.jar
4+
!**/src/main/**
5+
!**/src/test/**
6+
7+
### STS ###
8+
.apt_generated
9+
.classpath
10+
.factorypath
11+
.project
12+
.settings
13+
.springBeans
14+
.sts4-cache
15+
16+
### IntelliJ IDEA ###
17+
.idea
18+
*.iws
19+
*.iml
20+
*.ipr
21+
22+
### NetBeans ###
23+
/nbproject/private/
24+
/nbbuild/
25+
/dist/
26+
/nbdist/
27+
/.nb-gradle/
28+
build/
29+
30+
### VS Code ###
31+
.vscode/

springboot-graphql/README.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# 工程简介
2+
- Spring Boot 整合 GraphQL(新式API风格)项目搭建案例演示。
3+
4+
5+
# 工程搭建步骤
6+
###(1)创建一个 SpringBoot 项目,并引入 Maven 依赖
7+
```xml
8+
<dependencies>
9+
<dependency>
10+
<groupId>org.springframework.boot</groupId>
11+
<artifactId>spring-boot-starter</artifactId>
12+
</dependency>
13+
14+
<dependency>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-web</artifactId>
17+
</dependency>
18+
19+
<!--graphql start-->
20+
<dependency>
21+
<groupId>com.graphql-java</groupId>
22+
<artifactId>graphql-spring-boot-starter</artifactId>
23+
<version>5.0.2</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>com.graphql-java</groupId>
27+
<artifactId>graphql-java-tools</artifactId>
28+
<version>5.2.4</version>
29+
</dependency>
30+
<!--graphql end-->
31+
32+
<dependency>
33+
<groupId>org.projectlombok</groupId>
34+
<artifactId>lombok</artifactId>
35+
</dependency>
36+
</dependencies>
37+
38+
```
39+
40+
核心引入【graphql-spring-boot-starter】和【graphql-java-tools】。
41+
### (2)创建示例实体类 User 和 Post 
42+
#### ① User.java
43+
```java
44+
import lombok.Data;
45+
46+
import java.util.List;
47+
48+
@Data
49+
public class User {
50+
51+
private int userId;
52+
private String userName;
53+
private String realName;
54+
private String email;
55+
private List<Post> posts;
56+
57+
public User() {}
58+
59+
public User(int userId, String userName, String realName, String email) {
60+
this.userId = userId;
61+
this.userName = userName;
62+
this.realName = realName;
63+
this.email = email;
64+
}
65+
}
66+
```
67+
68+
69+
#### ② Post.java
70+
```java
71+
import lombok.Data;
72+
73+
@Data
74+
public class Post {
75+
private int postId;
76+
private String title ;
77+
private String text;
78+
private String category;
79+
private User user;
80+
81+
public Post() {}
82+
83+
public Post(int postId, String title, String text, String category) {
84+
this.postId = postId;
85+
this.title = title;
86+
this.text = text;
87+
this.category = category;
88+
}
89+
}
90+
```
91+
以上定义了两个 Java 实体:User 用户 和 Post 文章。
92+
93+
94+
###(3)编写 Schema 文件
95+
在 resources/schema 目录下创建 schema.graphqls 文件,内容如下:
96+
```yaml
97+
schema {
98+
query: Query,
99+
}
100+
101+
type Query {
102+
# 获取具体的用户
103+
getUserById(id:Int) : User
104+
# 获取具体的博客
105+
getPostById(id:Int) : Post
106+
}
107+
108+
type User {
109+
userId : ID!,
110+
userName : String,
111+
realName : String,
112+
email : String,
113+
posts : [Post],
114+
}
115+
116+
type Post {
117+
postId : ID!,
118+
title : String!,
119+
text : String,
120+
category: String
121+
user: User,
122+
}
123+
```
124+
> 注意:<br>
125+
> - 通过 type 关键字定义了两个对象(User 和 Post),在属性后面添加【!】表明这是一个非空属性,通过 【Post】表明这是一个 Post集合,类似于 Java对象中的 List。<br>
126+
> - 通过 Query 关键字定义了两个查询对象,getUserById,  getPostById,分别返回 User对象 和 Post对象。
127+
128+
graphql 的schema 相关语法见:[https://graphql.org/learn/schema](https://graphql.org/learn/schema)
129+
130+
131+
###(4)编写业务逻辑
132+
#### ① UserService.java
133+
```java
134+
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
135+
import com.google.common.collect.Lists;
136+
import edu.study.module.graphql.springbootgraphql.entity.Post;
137+
import edu.study.module.graphql.springbootgraphql.entity.User;
138+
import org.springframework.stereotype.Service;
139+
140+
import javax.annotation.PostConstruct;
141+
import java.util.List;
142+
143+
@Service
144+
public class UserService implements GraphQLQueryResolver {
145+
List<User> userList = Lists.newArrayList();
146+
147+
public User getUserById(int id) {
148+
return userList.stream().filter(item -> item.getUserId() == id).findAny().orElse(null);
149+
}
150+
151+
@PostConstruct
152+
public void initUsers() {
153+
Post post1 = new Post(1, "Hello,Graphql1", "Graphql初体验1", "日记");
154+
Post post2 = new Post(2, "Hello,Graphql2", "Graphql初体验2", "日记");
155+
Post post3 = new Post(3, "Hello,Graphql3", "Graphql初体验3", "日记");
156+
List<Post> posts = Lists.newArrayList(post1, post2, post3);
157+
158+
User user1 = new User(1, "zhangsan", "张三", "zhangsan@qq.com");
159+
User user2 = new User(2, "lisi", "李四", "lisi@qq.com");
160+
161+
user1.setPosts(posts);
162+
user2.setPosts(posts);
163+
164+
userList.add(user1);
165+
userList.add(user2);
166+
167+
}
168+
169+
}
170+
```
171+
172+
#### ② PostService.java
173+
```java
174+
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
175+
import edu.study.module.graphql.springbootgraphql.entity.Post;
176+
import edu.study.module.graphql.springbootgraphql.entity.User;
177+
import org.springframework.stereotype.Service;
178+
179+
@Service
180+
public class PostService implements GraphQLQueryResolver {
181+
/**
182+
* 为了测试,只查询id为1的结果
183+
*/
184+
public Post getPostById(int id) {
185+
if (id == 1) {
186+
User user = new User(1, "javadaily", "JAVA日知录", "zhangsan@qq.com");
187+
Post post = new Post(1, "Hello,Graphql", "Graphql初体验", "日记");
188+
post.setUser(user);
189+
return post;
190+
} else {
191+
return null;
192+
}
193+
194+
}
195+
}
196+
```
197+
基于 Graphql 的查询需要实现 GraphQLQueryResolver 接口,由于为了便于演示突出此文章的重点,这里并没有引入数据层(即DAO层)。
198+
199+
200+
###(5)配置 Graphql 断点
201+
```properties
202+
server.port = 8080
203+
graphql.servlet.corsEnabled=true
204+
# 配置端点
205+
graphql.servlet.mapping=/graphql
206+
graphql.servlet.enabled=true
207+
```
208+
> 配置完端口和端口点我们就可以对我们编写的 graphql 接口进行测试了。<br/>
209+
> 启动 Spring Boot 服务,测试书写query语句的接口地址为:http://localhost:8080/graphql
210+
211+
212+
# 延伸阅读
213+

springboot-graphql/pom.xml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>edu.study.module.graphql</groupId>
6+
<artifactId>springboot-graphql</artifactId>
7+
<version>0.0.1-SNAPSHOT</version>
8+
<name>springboot-graphql</name>
9+
<description>SpringBoot 整合 Graphql project for Spring Boot</description>
10+
11+
<properties>
12+
<java.version>1.8</java.version>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
15+
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-web</artifactId>
22+
</dependency>
23+
24+
<!--graphql start-->
25+
<dependency>
26+
<groupId>com.graphql-java</groupId>
27+
<artifactId>graphql-spring-boot-starter</artifactId>
28+
<version>5.0.2</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.graphql-java</groupId>
32+
<artifactId>graphql-java-tools</artifactId>
33+
<version>5.2.4</version>
34+
</dependency>
35+
<!--graphql end-->
36+
37+
<dependency>
38+
<groupId>org.projectlombok</groupId>
39+
<artifactId>lombok</artifactId>
40+
<optional>true</optional>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-test</artifactId>
45+
<scope>test</scope>
46+
<exclusions>
47+
<exclusion>
48+
<groupId>org.junit.vintage</groupId>
49+
<artifactId>junit-vintage-engine</artifactId>
50+
</exclusion>
51+
</exclusions>
52+
</dependency>
53+
</dependencies>
54+
55+
<dependencyManagement>
56+
<dependencies>
57+
<dependency>
58+
<groupId>org.springframework.boot</groupId>
59+
<artifactId>spring-boot-dependencies</artifactId>
60+
<version>${spring-boot.version}</version>
61+
<type>pom</type>
62+
<scope>import</scope>
63+
</dependency>
64+
</dependencies>
65+
</dependencyManagement>
66+
67+
<build>
68+
<plugins>
69+
<plugin>
70+
<groupId>org.apache.maven.plugins</groupId>
71+
<artifactId>maven-compiler-plugin</artifactId>
72+
<version>3.8.1</version>
73+
<configuration>
74+
<source>1.8</source>
75+
<target>1.8</target>
76+
<encoding>UTF-8</encoding>
77+
</configuration>
78+
</plugin>
79+
<plugin>
80+
<groupId>org.springframework.boot</groupId>
81+
<artifactId>spring-boot-maven-plugin</artifactId>
82+
<version>2.3.7.RELEASE</version>
83+
<configuration>
84+
<mainClass>edu.study.module.graphql.springbootgraphql.SpringbootGraphqlApplication</mainClass>
85+
</configuration>
86+
<executions>
87+
<execution>
88+
<id>repackage</id>
89+
<goals>
90+
<goal>repackage</goal>
91+
</goals>
92+
</execution>
93+
</executions>
94+
</plugin>
95+
</plugins>
96+
</build>
97+
98+
</project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package edu.study.module.graphql.springbootgraphql;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
/**
7+
* @author drew
8+
*/
9+
@SpringBootApplication
10+
public class SpringbootGraphqlApplication {
11+
12+
public static void main(String[] args) {
13+
SpringApplication.run(SpringbootGraphqlApplication.class, args);
14+
}
15+
16+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package edu.study.module.graphql.springbootgraphql.entity;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* @author zl
7+
* @create 2021-04-26 17:38
8+
*/
9+
@Data
10+
public class Post {
11+
private int postId;
12+
private String title ;
13+
private String text;
14+
private String category;
15+
private User user;
16+
17+
public Post() {
18+
19+
}
20+
21+
public Post(int postId, String title, String text, String category) {
22+
this.postId = postId;
23+
this.title = title;
24+
this.text = text;
25+
this.category = category;
26+
}
27+
}

0 commit comments

Comments
 (0)