Graphql基本概念和使用
graphql是一什么?
graphql接口調用規范,graphql在框架上通過模型定義文件感知了模型的存在,所以可以動態指定返回值的需要返回哪些,比如有一個接口有100個返回值字段,可以指定需要那幾個。
postman里面有對graphql的特殊支持。

其實直接發送post請求也行,只是這樣參數不好看,也不好修改

graphql在springboot中的使用
導入依賴,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
<version>2.7.8</version>
</dependency>
修改配置文件(不改也行,這里重要的是graphiql的開啟,類似一個調試界面)
## web ##
server:
servlet:
context-path: /
port: 8088
spring:
graphql:
graphiql:
enabled: true
websocket:
path: /graphql
schema:
printer:
enabled: true
locations: classpath:/graphql #test.graphql文件位置
file-extensions: .graphql
寫幾個對象和他們的查詢和修改的方法
public class Book {
private Long id;
private String name;
private User owner;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
public class User {
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
對user和book查詢和修改的方法
@QueryMapping 對應查詢
@MutationMapping 對應的寫入
@Controller
public class GraphqlTestController {
Map<Long, User> users = new HashMap<>();
Map<Long, Book> books = new HashMap<>();
@QueryMapping
public String hello(){
return "hello graphql";
}
@QueryMapping
public User getUserById(@Argument Long id) {
System.out.println("id:"+id);
return users.get(id);
}
@MutationMapping
public int addUser(@Argument Long id) {
System.out.println("id:"+id);
User user = new User();
user.setId( id );
users.put(user.getId(),user);
return users.size();
}
@MutationMapping
public User addBook(@Argument Long id,@Argument String name,@Argument Long userId) {
System.out.println("id:"+id);
Book book = new Book();
book.setId(id);
book.setName("name");
book.setOwner( users.get(userId) );
return book.getOwner();
}
}
創建文件resources\graphql\schema.graphql
這個是定義模板和有哪些接口的約束文件
# @QueryMapping 標注的方法,里面定義的需要和對應方法參數返回值對應
type Query {
getUserById(id:String!) : String
hello:String
}
# @MutationMapping 標注的方法,里面定義的需要和對應方法參數返回值對應
type Mutation {
addUser(id:Int): Int
addBook(id:String,name:String,userId:String): User!
}
# 這個和Book 對應的GraphqlTestController里面 導入的 xxx.Book,所以只是同名匹配,包名又GraphqlTestController導入決定
type Book {
id: String
name: String
owner: User
}
# 對應 User對象
type User {
id: String
name: String
age: Int
}
graphql的語法
當我們在配置文件中開啟以后graphiql以后
spring:
graphql:
graphiql:
enabled: true
可以使用調試界面:http://127.0.0.1:8088/graphiql

點擊執行的時候實際上它發送的是一個post請求,請求的地址是:http://127.0.0.1:8088/graphql,也就是前面物品截圖postman請求的地址

請求參數格式大概是這樣的
# query或者mutation表示查詢或者寫入
# 參數列表寫法類似json,但是外面是是小括號
# 返回值列表是大括號包裹起來的,里面沒有逗號分割,一個屬性一行,如果只有一個字段的返回值直接不寫大括號
query/mutation{
調用的方法名字(參數1:"參數1的值",參數2:"參數2的值"){
返回字段1
返回字段2
}
}
如果在post里面發送外面還有一層query
{
"query": "mutation{\n addAuthor(id:2)\n}"
}
然后看看 schema.graphql文件的定義
模型對象的映射大概是這樣的
type 對象名字{
屬性1: 類型
屬性2: 類型
屬性3: 類型
}
# 這個和Book 對應的GraphqlTestController里面 導入的 xxx.Book,所以只是同名匹配,包名又GraphqlTestController導入決定
type Book {
id: String
name: String
owner: User
}
# 對應 User對象
type User {
id: String
name: String
age: Int
}
方法對象的定義,
type Query/Mutation {
方法1(參數1:類型) : 返回值
方法2:返回值
}
# 下面的!表示必填參數,
# 如果返回值是數據組用[類型]括起來,比如[User] 表示User集合
# @QueryMapping 標注的方法,里面定義的需要和對應方法參數返回值對應
type Query {
getUserById(id:String!) : String
hello:String
}
# @MutationMapping 標注的方法,里面定義的需要和對應方法參數返回值對應
type Mutation {
addUser(id:Int): Int
addBook(id:String,name:String,userId:String): User!
}
graphsql的數據類型沒有Long,只有Int和String,float之類的,可以直接使用String代替,并且默認會類型轉換,但是不清楚會不會丟精度,了解不深,也沒打算大量使用,所以沒做 更加深入的了解。
優缺點(個人觀點)
優點:很明顯graphql這個框架通過模型文件感知了返回值類型,所以他最大的優點在于可以動態指定返回哪些參數,這樣在后端提供大而且全的接口的時候前端可以通過指定返回值節省一些服務器的帶寬,但是這需要前端知道這個接口有哪些參數。
缺點:這個語法對比restful+json明顯更加復雜,不是通用的法語,可讀性更低。修改成本也會更高,以前的修改成本是實體類加方法,現在需要多維護實體類模型和方法定義模型。
缺點2:所有的請求都在一個接口,請求地址一樣,只是參數不一樣我們對瀏覽器緩存的控制可能會變得更加困難,協商緩存的控制大概也不能用了。在外層有權限控制的系統里面,感覺通過這個接口留后門是不錯的方法,因為只用開通一個接口權限就能調用所有graphql的接口,但是,這個接口風險可能會很高,需要慎重使用。
一個技術只要有一個閃光點就有存在的必要,但是如果它要取代現有的技術一定是全方面領先才行,感覺graphql有閃光點,但是和通常使用的restful+json來說并沒有太多的優勢。
能耍的時候就一定要耍,不能耍的時候一定要學。
--天道酬勤,貴在堅持posted on 2025-02-05 18:02 zhangyukun 閱讀(368) 評論(0) 收藏 舉報
浙公網安備 33010602011771號