您好,登錄后才能下訂單哦!
這篇文章主要介紹了GraphQL如何創建的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇GraphQL如何創建文章都會有所收獲,下面我們一起來看看吧。
因為目前做的項目查詢提供的接口都使用GraphQL替代典型的REST API,所以有必要去對它進行了解和源碼的閱讀。一種用于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中指定的字段相同。
關于“GraphQL如何創建”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“GraphQL如何創建”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。