GraphQL在Wildfly群上
“ GraphQL是API的查詢語言,是用于使用現有數據完成這些查詢的運行時。 GraphQL為您的API中的數據提供了一個完整且易于理解的描述,使客戶能夠準確地詢問他們所需的內容,僅此而已,使隨著時間的推移更容易開發API并啟用強大的開發人員工具。
–來自https://graphql.org/
任何已經構建了可供多個消費者使用的REST服務的人,例如其他服務,網站或移動設備,都將知道很難構建滿足所有需求的完美端點。 對于所有這些特殊情況,您通常最終都會獲得相同服務的變體:)
現在,我們都知道我們應該只使用HATEOAS …,它在我的TODO列表中(承諾!),直到我偶然發現GraphQL為止 。
因此,在此博客文章中,我將解釋如何輕松地將GraphQL添加到現有的JAX-RS應用程序中。
示例項目
Github中提供了示例項目,并且非常容易上手。
git clone https://github.com/phillip-kruger/membership.git cd membership mvn clean install這將使用示例應用程序http:// localhost:8080 / membership /來啟動fatjar wildfly-swarm
高水平
該示例是基本的成員資格服務,您可以在其中獲得所有成員或特定成員。 您可以添加,編輯和刪除成員。
該應用程序是典型的JAX-RS,CDI,EJB,JPA,Bean驗證Java EE應用程序,并且我們正在添加一個新的GraphQL端點。
GraphQL部分使用以下庫:
- graphql-java
- graphql-java-servlet
- graphQL-spqr
- 石墨烯
我添加來將現有的JAX-RS公開為GraphQL的唯一Java類:
- MembershipGraphQLListener –注冊“ / graphql” Servlet偵聽器。
- MembershipGraphQLApi – GraphQL端點。 僅包裝現有的@Stateless服務。
- MembershipErrorHandler –處理異常。
使用graphQL-spqr的注釋, MembershipGraphQLApi類實際上只是描述和包裝了現有的@Stateless服務:
@RequestScopedpublic class MembershipGraphQLApi {@Injectprivate MembershipService membershipService;// ...@GraphQLQuery(name = "memberships")public List<Membership> getAllMemberships(Optional<MembershipFilter> filter,@GraphQLArgument(name = "skip") Optional<Integer> skip,@GraphQLArgument(name = "first") Optional<Integer> first) {return membershipService.getAllMemberships(filter, skip, first); }// ...}我的希望–我們很快將在Java EE(或Jakarta EE或MicroProfile)中提供一個JAX-QL(或其他東西),以使其變得更加簡單!
首先是一些REST
我正在使用MicroProfile OpenAPI和Swagger UI為REST端點創建Open API定義。
您可以使用http:// localhost:8080 / membership / rest / openapi-ui /測試一些查詢
示例 –獲取所有成員資格:
GET http://localhost:8080/membership/rest
這將返回:
[{"membershipId": 1,"owner": {"id": 1,"names": ["Natus","Phillip"],"surname": "Kruger"},"type": "FULL"},{"membershipId": 2,"owner": {"id": 2,"names": ["Charmaine","Juliet"],"surname": "Kruger"},"type": "FULL"},{"membershipId": 3,"owner": {"id": 3,"names": ["Koos"],"surname": "van der Merwe"},"type": "FULL"},{"membershipId": 4,"owner": {"id": 4,"names": ["Minki"],"surname": "van der Westhuizen"},"type": "FREE"}]示例 –獲得一定的成員資格(1):
GET http://localhost:8080/membership/rest/1
這將返回:
{"membershipId": 1,"owner": {"id": 1,"names": ["Natus","Phillip"],"surname": "Kruger"},"type": "FULL"}現在讓我們看一下GraphQL
該應用程序包括GraphiQL UI(作為Webjar),可以輕松測試一些GraphQL查詢
您可以使用http:// localhost:8080 / membership / graph / graphiql /測試一些查詢
因此,讓我們看看GraphQL是否兌現了“不再需要過度提取和提取不足”的承諾。
獲取所有成員資格和所有字段(與REST相同)
query Memberships {memberships{...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname }這將返回所有值,但是,現在很容易定義應包括哪些字段…
獲取所有會員資格,但僅包括id字段
query Memberships {memberships{...membershipIdentifiers}}fragment membershipIdentifiers on Membership {membershipId}現在產生的有效負載要小得多:
{"data": {"memberships": [{"membershipId": 1},{"membershipId": 2},{"membershipId": 3},{"membershipId": 4}]}}現在,僅獲取特定類型的會員資格(因此,獲取所有免費會員資格)
query FilteredMemberships {memberships(filter:{type:FREE}){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname }這將僅返回免費會員資格。 好酷!
甚至更好,所有姓氏的成員都以“ Kru”開頭
query FilteredMemberships {memberships(filter:{surnameContains: "Kru"}){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname }太好了! 我們找到了兩個人:
{"data": {"memberships": [{"membershipId": 1,"owner": {"id": 1,"names": ["Natus","Phillip"],"surname": "Kruger"},"type": "FULL"},{"membershipId": 2,"owner": {"id": 2,"names": ["Charmaine","Juliet"],"surname": "Kruger"},"type": "FULL"}]}}使用客戶端上的變量獲取特定的成員資格:
query Membership($id:Int!) {membership(membershipId:$id){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname }變量:
{"id":1}在特定條件下包括字段:
query Membership($id:Int!,$withOwner: Boolean!) {membership(membershipId:$id){...fullMembership}}fragment fullMembership on Membership {membershipIdowner @include(if: $withOwner){...owner}type}fragment owner on Person {idnamessurname }變量:
{"id":1,"withOwner": false}這將排除所有者(正確包括):
{"data": {"membership": {"membershipId": 1,"type": "FULL"}}}分頁
讓我們使用get all查詢,但要分頁。
query Memberships($itemsPerPage:Int!,$pageNumber:Int!) {memberships(first:$itemsPerPage,skip:$pageNumber) {membershipIdowner{namessurname}type}}變量:
{"itemsPerPage": 2,"pageNumber": 1}這將返回前2個結果,然后您可以通過增加“ pageNumber”值來進行分頁。
變異
創建
mutation CreateMember {createMembership(membership: {type:FULL,owner: {names: "James",surname:"Small"}}) {membershipId}}這將創建新的成員資格并返回ID。
更新資料
mutation EditMember($membership: MembershipInput!) {createMembership(membership:$membership) {membershipId}}變量:
{"membership": {"membershipId": 2,"owner": {"names": ["Charmaine","Juliet"],"surname": "Krüger"},"type": "FULL"}}(在克魯格大學添加了變音符號,現在應該是克魯格)
刪除
mutation DeleteMembership($id:Int!){deleteMembership(membershipId:$id){membershipId}}變量:
{"id":1}這將刪除成員資格1。
例外。
MembershipErrorHandler轉換一個ConstraintViolationException(在bean驗證失敗時拋出),并為GraphQL創建一個不錯的錯誤消息。
因此,讓我們嘗試創建一個姓氏僅為一個字母的成員。
mutation CreateMember($membership: MembershipInput!) {createMembership(membership:$membership) {membershipId}}變量:
{"membership": {"owner": {"names": "Christina","surname": "S"},"type": "FULL"}}這將返回bean驗證錯誤消息:
{"data": {"createMembership": null},"errors": [{"message": "Surname 'S' is too short, minimum 2 characters","path": null,"extensions": null}]}如果您查看Person POJO:
@NotNull(message = "Surname can not be empty") @Size(min=2, message = "Surname '${validatedValue}' is too short, minimum {min} characters")private String surname;內省
GraphQL的另一個好處是,它具有可查詢的架構和類型系統:
{__schema {queryType {namefields {name}}mutationType{namefields{name}}subscriptionType {namefields{name}}}}上面將描述此端點上可用的查詢和變異。
您還可以描述您的模型:
{__type(name: "Membership") {namekindfields {nameargs {name}}}}摘要
在此示例中,我們沒有刪除REST,只是添加了GraphQL作為使用者的替代選項。
到現在為止,應該清楚的是,客戶端具有更多的選項來完全根據需要過濾和查詢數據。 所有這些都無需服務器做任何額外的工作。 這樣可以在客戶端進行快速的產品迭代。
線上的有效負載已得到優化,我們正在節省帶寬!
再次,我希望–我們很快將在Java EE(或Jakarta EE或MicroProfile)中提供一個JAX-QL(或其他東西),以使其變得更加簡單!
翻譯自: https://www.javacodegeeks.com/2018/05/graphql-on-wildfly-swarm.html
總結
以上是生活随笔為你收集整理的GraphQL在Wildfly群上的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java微妙_编码Java时的10个微妙
- 下一篇: javafx 示例_示例介绍:JavaF