Spring Boot和Netflix DGS的GraphQL原始碼案例
Netflix Domain Graph Service(DGS)是在Netflix內部建立的一個新的開放原始碼框架,該框架簡化並幫助了使用GraphQL實施Spring Boot應用程式。
DGS的特徵:
- 它是一個基於Spring Boot樣式的註釋的系統。
- 與Spring Security整合。
- 錯誤管理。
- 適用於Java的GraphQL客戶端。
- 支援WebSockets,SSE,檔案上傳或GraphQL Federation。
Netflix的域圖服務(DGS)框架極大地促進了帶有Spring Boot的GraphQL的開發,從而能夠以更簡單的方式構建任何API。由於GraphQL的適應性和靈活性以及其他特性,它被定位為Rest的廣泛使用的替代方法,因此使用GraphQL的頻率越來越高。
案例說明
完整的示例在github上。
這個示例中,將使用帶有H2的記憶體關聯式資料庫,以簡化使用JPA的示例。我們的示例將由三個非常基本的實體組成:銀行,使用者和帳戶銀行,其中使用者在銀行中有一個或N個銀行帳戶,而一個銀行有1個或N個銀行帳戶。
在我們的應用程式中,使用Lombok簡化刪除Java樣板。
新增依賴:
<dependency> <groupId>com.netflix.graphql.dgs</groupId> <artifactId>graphql-dgs-spring-boot-starter</artifactId> <version>${netflix-dgs.version}</version> </dependency> |
有必要為我們的應用程式新增更多的依賴項。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> |
建立GraphQL的Schema
與建立關聯式資料庫的表結構一樣,我們將對GraphQL進行相同的操作,即建立schema。我們建立的必須位於以下路徑/ src / main / resources / schema中,並且在此路徑中,Netflix DGS將負責載入模式。
對於每個模式,我們建立了一個副檔名為graphqls的不同檔案。其中有一個QueryResolver型別,它將具有兩個不同的搜尋,以及一個MutationResolver以便能夠在資料庫中建立物件。
建立3個不同的方案,帳戶,使用者和銀行:
type QueryResolver { users: [User] user(id: ID!): User! } type MutationResolver { createUser(user: UserInput!): User } input UserInput { firstName: String! lastName: String! address: String! country: String! city: String! age: Int } type User { id: ID! firstName: String! lastName: String! address: String! country: String! city: String! age: Int! bank: Bank accounts: [Account] } schema { query: QueryResolver mutation: MutationResolver } |
在Spring Boot中建立實體
接下來,我們將建立負責對映關聯式資料庫和GraphQL模式的實體。
@Entity @AllArgsConstructor @NoArgsConstructor @Getter @Setter public class User { @Id @GeneratedValue private UUID id; private String firstName; private String lastName; private int age; private String address; private String country; private String city; @OneToMany(mappedBy = "user") private Set<Account> accounts; @ManyToOne() private Bank bank; } |
建立變化物件
如前所述,我們已經為每個架構建立了一個MutationResolver型別,因此我們需要建立一個新的物件,並傳遞該物件來建立它。也就是說,它將是與之進行繫結的物件,當進行請求和呼叫時,它將具有與我們在模式中輸入的名稱相同的名稱。
@AllArgsConstructor @NoArgsConstructor @Getter @Setter public class UserInput { private String firstName; private String lastName; private int age; private String address; private String country; private String city; } |
使用Spring Boot建立儲存庫
對於永續性或儲存庫層,我們將使用JpaRepository,它將為我們提供所有JPA工具,使其能夠儲存和查詢我們的資料庫物件。
例如,對於“帳戶”,如下所示:
public interface AccountRepository extends JpaRepository<Account, UUID> { } |
Spring Boot的Netflix DGS
Netflix已經建立了它的基於註釋的DGS框架,該框架由Spring Boot支援。下面我們展示了要使應用程式與GrpahQL和Spring Boot一起執行時要考慮的基本註釋。
- @DgsComponent:此批註負責指示類將要執行查詢。該類應在定義中帶有此註釋。
- @DgsData,每個帶有邏輯以執行查詢的方法都必須使用@DgsData進行註釋。我們將在其中新增父型別的位置,這是架構的型別以及在架構中定義的欄位。
- @InputArgument,用於定義在查詢中作為引數傳遞的引數。
- @DgsQuery,是parentType為query時@DgsData的縮寫。
- @DgsMutation,是parentType為Mutation時@DgsData的縮寫。
使用DGS時要記住的另一個問題是能夠通過實現DgsCustomContextBuilder類來建立自己的上下文。您可以使用它來記錄或儲存狀態,或儲存一些通過DataFetchingEnvironment類訪問的資訊。在示例類UserQuery中,您可以看到其用法。
在Spring Boot中使用Netflix DGS查詢
Netflix DGS的查詢類使用了我們上面提到的一些註釋:
@DgsComponent @RequiredArgsConstructor public class UserQuery { private final UserRepository userRepository; private final CustomContextBuilder contextBuilder; @DgsData(parentType = "QueryResolver", field = "users") public Iterable<User> findAll(DgsDataFetchingEnvironment dfe) { var users = (List<User>) userRepository.findAll(); contextBuilder.customContext(users, null, null).build(); return users; } @DgsData(parentType = "QueryResolver", field = "user") public User findById(@InputArgument("id") String id, DataFetchingEnvironment dfe) { CustomContext customContext = DgsContext.getCustomContext(dfe); var users = customContext.getUsers(); if (null != users) { var user = users.stream().filter(u -> u.getId().equals(UUID.fromString(id))).findFirst(); return user.orElseGet(() -> userRepository.findById(UUID.fromString(id)).orElseThrow(DgsEntityNotFoundException::new)); } else { return userRepository.findById(UUID.fromString(id)).orElseThrow(DgsEntityNotFoundException::new); } } } |
該類的一個亮點是CustomContextBuilder的使用,該類建立了自己的上下文,在該上下文中新增了不同的返回物件,然後可以直接對其進行訪問。
在Spring Boot中使用Netflix DGS進行更改
接下來,我們將看到UserMutation類,該類負責在資料庫中儲存新使用者。
如您在@DgsData中所看到的,我們首先指示parentType是MutationResolver,欄位是createUser,它與模式中的定義匹配。
@DgsComponent @RequiredArgsConstructor public class UserMutation { private final UserRepository userRepository; @DgsData(parentType = "MutationResolver", field = "createUser") public User createUser(@InputArgument("user") UserInput user) { return userRepository.save(new User(null, user.getFirstName(), user.getLastName(), user.getAge(), user.getAddress(), user.getCountry(), user.getCity(), null, null)); } } |
使用Spring Boot測試Netflix DGS應用程式
完成應用程式並全部實現後,就可以啟動一些查詢了。
我們使用以下命令執行我們的應用程式:mvn spring-boot:run
我們訪問頁面 http://localhost:8080/graphiql,然後會出現一個介面,我們可以在其中啟動查詢。
相關文章
- Netflix釋出用於Spring Boot的GraphQL的開源服務框架DGSSpring Boot框架
- Spring Boot + GraphQL建立API的開源案例Spring BootAPI
- 開始使用GraphQL Java和Spring BootJavaSpring Boot
- GraphQL SPQR和Spring Boot入門 | baeldungSpring Boot
- Spring Boot下的一個DDD案例原始碼介紹Spring Boot原始碼
- Spring Boot整合Spring Cloud Netflix元件Spring BootCloud元件
- Spring Boot系列(四):Spring Boot原始碼解析Spring Boot原始碼
- 使用Spring Boot實現的GraphQL示例Spring Boot
- SpringBootHibernateJPA: Spring Boot+ JPA資訊系統案例原始碼Spring Boot原始碼
- Spring Boot實現DDD的貨運Cargo微服務案例原始碼Spring BootCargo微服務原始碼
- 使用Spring Boot和GraphQL構建靈活的API服務Spring BootAPI
- 使用Docker實現Spring Boot Restful Web服務案例原始碼DockerSpring BootRESTWeb原始碼
- Spring Boot和EventStoreDB事件溯源案例Spring Boot事件
- Spring Boot系列(三):Spring Boot整合Mybatis原始碼解析Spring BootMyBatis原始碼
- Spring GraphQL與Netflix領域圖服務框架整合Spring框架
- Spring Boot + JPA DataTable原始碼Spring Boot原始碼
- 使用Spring Boot排程WebSocket推送的教程和原始碼 - BaeldungSpring BootWeb原始碼
- Spring Data JPA原始碼案例Spring原始碼
- Netflix採用GraphQL的經驗分享
- 精盡Spring Boot原始碼分析 - 序言Spring Boot原始碼
- Spring Boot 自動配置 原始碼分析Spring Boot原始碼
- 結合GraalVM與Spring Native的Spring Boot原始碼教程 | foojayLVMSpring Boot原始碼
- Spring Boot支援Java 16和新的Java記錄原始碼教程 | foojaySpring BootJava原始碼
- Spring Boot GraphQL 實戰 01_快速入門Spring Boot
- java工程管理系統原始碼+spring cloud + spring bootJava原始碼CloudSpring Boot
- 精盡MyBatis原始碼分析 - Spring-Boot-Starter 原始碼分析MyBatis原始碼Springboot
- Spring Boot的Clean架構教程與原始碼 - BaeldungSpring Boot架構原始碼
- Spring Boot原始碼分析-啟動過程Spring Boot原始碼
- Spring Boot + Junit 5 + Testcontainers原始碼專案Spring BootAI原始碼
- 基於Istio/gRPC/Redis/BigQuery/Spring Boot/Spring Cloud和Stackdriver的微服務案例RPCRedisSpring BootCloud微服務
- Apache Camel與Spring-boot和Kafka的整合開源案例ApacheSpringbootKafka
- 企業工程管理系統原始碼+spring cloud + spring boot原始碼CloudSpring Boot
- java+spring cloud + spring boot工程管理系統原始碼JavaCloudSpring Boot原始碼
- Spring Boot GraphQL 實戰 02_增刪改查和自定義標量Spring Boot
- GraphQL案例演示
- Spring Boot中的Firebase身份驗證+Firestore整合原始碼Spring BootREST原始碼
- Spring Boot 整合 Spring Security 入門案例教程Spring Boot
- Spring Boot React 全棧 Web 開發原始碼Spring BootReact全棧Web原始碼