<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
因為目前做的專案查詢提供的介面都使用GraphQL替代典型的REST API,所以有必要去對它進行了解和原始碼的閱讀。本篇主要大致瞭解下GraphQL。
一種用於API的查詢語言,讓你的請求資料不多不少。前端按需獲取,後端動態返回(不需要的資料不會返回甚至不會查庫),對比起典型的REST API將更加靈活,後端程式碼提供可選能力。如果增加新的欄位應用不想處理這部分資料可以不用區分版本。
後端確定哪些介面行為是被允許的,前端按需獲取資料,讓你的請求資料不多不少。
詳細的介紹可以參考官方首頁配合動圖更加清晰。
最好使用Spring Initializr去建立一個新的專案,不會產生一些衝突。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.graphql-java.tutorial</groupId> <artifactId>book-details</artifactId> <version>0.0.1-SNAPSHOT</version> <name>book-details</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java</artifactId> <version>11.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java-spring-boot-starter-webmvc --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-spring-boot-starter-webmvc</artifactId> <version>1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>26.0-jre</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>central</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <layout>default</layout> <!-- 是否開啟發布版構件下載 --> <releases> <enabled>true</enabled> </releases> <!-- 是否開啟快照版構件下載 --> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
在src/main/resources
中建立schema.graphqls
檔案:
type Query { bookById(id: ID): Book } type Book { id: ID name: String pageCount: Int author: Author } type Author { id: ID firstName: String lastName: String }
可以看到定義了一個bookById查詢,用於根據id查詢書籍,書籍中包含id、name、pageCount、author屬性,其中author是一個複合型別所以定義了type Author
。
上面顯示的用於描述schema的特定於域的語言稱為schema定義語言或SDL。更多細節可以在這裡找到。
一旦我們有了這個檔案,我們需要通過讀取檔案並解析它並且新增程式碼來為它獲取資料使它“栩栩如生”。
package com.graphqljava.tutorial.bookdetails; import com.google.common.base.Charsets; import com.google.common.io.Resources; import graphql.GraphQL; import graphql.schema.GraphQLSchema; import graphql.schema.idl.RuntimeWiring; import graphql.schema.idl.SchemaGenerator; import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeDefinitionRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.IOException; import java.net.URL; import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; @Component public class GraphQLProvider { private GraphQL graphQL; /** * 注入GraphQL範例,GraphQL Java Spring介面卡將使用GraphQL範例使我們的schema可用,通過Http-使用預設的"/graphql"url路徑 * * @return */ @Bean public GraphQL graphQL() { return graphQL; } @PostConstruct public void init() throws IOException { //使用Resources讀取graphqls檔案 URL url = Resources.getResource("schema.graphqls"); //拿到graphqls檔案內容 String sdl = Resources.toString(url, Charsets.UTF_8); GraphQLSchema graphQLSchema = buildSchema(sdl); this.graphQL = GraphQL.newGraphQL(graphQLSchema).build(); } @Autowired GraphQLDataFetchers graphQLDataFetchers; /** * 建立GraphQLSchema範例:解析schema並關聯fetcher * * @param sdl * @return */ private GraphQLSchema buildSchema(String sdl) { TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl); RuntimeWiring runtimeWiring = buildWiring(); SchemaGenerator schemaGenerator = new SchemaGenerator(); return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring); } /** * 根據層級去關聯fetcher構建RuntimeWiring。最外層為Query可以提供bookById所需引數。第二層為Book-經過第一層獲得的,可以為author提供所需引數。 * * @return */ private RuntimeWiring buildWiring() { return RuntimeWiring.newRuntimeWiring() .type(newTypeWiring("Query") .dataFetcher("bookById", graphQLDataFetchers.getBookByIdDataFetcher())) .type(newTypeWiring("Book") .dataFetcher("author", graphQLDataFetchers.getAuthorDataFetcher())) .build(); } }
package com.graphqljava.tutorial.bookdetails; import com.google.common.collect.ImmutableMap; import graphql.schema.DataFetcher; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; import java.util.Map; @Component public class GraphQLDataFetchers { /** * books靜態資料 */ private static List<Map<String, String>> books = Arrays.asList( ImmutableMap.of("id", "book-1", "name", "Harry Potter and the Philosopher's Stone", "pageCount", "223", "authorId", "author-1"), ImmutableMap.of("id", "book-2", "name", "Moby Dick", "pageCount", "635", "authorId", "author-2"), ImmutableMap.of("id", "book-3", "name", "Interview with the vampire", "pageCount", "371", "authorId", "author-3") ); /** * autors靜態資料 */ private static List<Map<String, String>> authors = Arrays.asList( ImmutableMap.of("id", "author-1", "firstName", "Joanne", "lastName", "Rowling"), ImmutableMap.of("id", "author-2", "firstName", "Herman", "lastName", "Melville"), ImmutableMap.of("id", "author-3", "firstName", "Anne", "lastName", "Rice") ); /** * bookById的fetcher,這裡只是簡單的通過靜態資料進行篩選,具體生產使用sql進行查詢 * * @return */ public DataFetcher getBookByIdDataFetcher() { return dataFetchingEnvironment -> { // 獲得查詢篩選引數 String bookId = dataFetchingEnvironment.getArgument("id"); return books .stream() .filter(book -> book.get("id").equals(bookId)) .findFirst() .orElse(null); }; } /** * 第二層author fetcher * * @return */ public DataFetcher getAuthorDataFetcher() { return dataFetchingEnvironment -> { //獲得上級物件 Map<String, String> book = dataFetchingEnvironment.getSource(); //根據上級物件找到關聯id(相當於外來鍵) String authorId = book.get("authorId"); return authors .stream() .filter(author -> author.get("id").equals(authorId)) .findFirst() .orElse(null); }; } }
對於GraphQL Java伺服器來說,最重要的概念可能是DataFetcher:DataFetcher在執行查詢時獲取一個欄位的資料。
GraphQL Java在執行查詢時,會為查詢中遇到的每個欄位呼叫相應的DataFetcher。DataFetcher是函數介面,函數具有一個引數為DataFetchingEnvironment型別。
public interface DataFetcher<T> { T get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception; }
如上我們實現了兩個DataFetchers。如上所述,如果你不指定一個,PropertyDataFetcher則是被預設使用。比如上面的例子中Book.id,Book.name,Book.pageCount,Author.id,Author.firstName和Author.lastName都有一個PropertyDataFetcher與之關聯。
PropertyDataFetcher嘗試以多種方式查詢Java物件的屬性。如果是java.util.Map
,簡單的通過key查詢。這對我們來說非常好,因為book和author Maps的keys與schema中指定的欄位相同。
Getting started with Spring Boot
以上就是GraphQL入門總體建立教學的詳細內容,更多關於GraphQL建立教學的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45