GraphQL SPQR(GraphQl架構發布者和Query Resolver,發音為Speaker )是一個簡單使用的庫,用於快速開發Java中GraphQL API。
GraphQL SPQR的目的是使在任何Java項目中添加GraphQl API簡單。它通過動態生成Java代碼的GraphQL模式來起作用。
在開發啟用GraphQL的應用程序時,通常首先定義架構並在以後連接業務邏輯。這被稱為架構優先風格。儘管它具有優勢,但具有強烈和靜態的語言,例如Java,但會導致很多重複。
例如,簡單的GraphQl類型的模式定義可以喜歡:
type Link {
id : ID !
url : String !
description : String
}
而且,通常,系統中存在相應的Java類型,類似於以下幾個:
public class Link {
private final String id ;
private final String url ;
private final String description ;
//constructors, getters and setters
//...
}
這兩個塊都包含完全相同的信息。更糟糕的是,更改需要立即改變另一個。這使重構風險和笨拙,編譯器無法幫助。另一方面,如果您試圖將GraphQl API引入現有項目,則編寫模式實際上意味著重新描述整個現有模型。這既昂貴又容易出錯,仍然遭受重複和缺乏工具的困擾。
相反,GraphQL SPQR通過從現有模型中生成架構來採用代碼優先的方法。這使模式和模型保持同步,從而減輕了重構。它在現有代碼庫頂部引入GraphQL的項目中也可以很好地工作。
請注意,以代碼優先的方式開發仍然有效地是架構優先,其不同是,您不是使用另一種語言來開發模式,而是在Java中使用IDE,編譯器和所有工具為您提供幫助。破壞模式的變化意味著編譯將失敗。無需襯里或其他脆弱的黑客。
GraphQL SPQR部署到Maven Central。
小牛
< dependency >
< groupId >io.leangen.graphql</ groupId >
< artifactId >spqr</ artifactId >
< version >0.12.3</ version >
</ dependency >
gradle
compile ' io.leangen.graphql:spqr:0.12.3 '
該示例將使用GraphQl SPQR本身提供的註釋,但是這些是可選的,並且映射是完全可配置的,從而使現有服務可以通過GraphQL實現而無需修改。
服務課:
class UserService {
@ GraphQLQuery ( name = "user" )
public User getById ( @ GraphQLArgument ( name = "id" ) Integer id ) {
...
}
}
如果要跳過添加@GraphQLArgument
,則使用-parameters
選項編譯,否則名稱將丟失。
域類:
public class User {
private String name ;
private Integer id ;
private Date registrationDate ;
@ GraphQLQuery ( name = "name" , description = "A person's name" )
public String getName () {
return name ;
}
@ GraphQLQuery
public Integer getId () {
return id ;
}
@ GraphQLQuery ( name = "regDate" , description = "Date of registration" )
public Date getRegistrationDate () {
return registrationDate ;
}
}
要將其他字段附加到User
GraphQL類型,而無需修改User
類,只需添加一個將User
作為上下文的查詢即可。最簡單的方法是使用@GraphQLContext
註釋:
class UserService {
... //regular queries, as above
// Attach a new field called twitterProfile to the User GraphQL type
@ GraphQLQuery
public TwitterProfile twitterProfile ( @ GraphQLContext User user ) {
...
}
}
用GraphQL-SPQR公開服務:
UserService userService = new UserService (); //instantiate the service (or inject by Spring or another framework)
GraphQLSchema schema = new GraphQLSchemaGenerator ()
. withBasePackages ( "io.leangen" ) //not mandatory but strongly recommended to set your "root" packages
. withOperationsFromSingleton ( userService ) //register the service
. generate (); //done ;)
GraphQL graphQL = new GraphQL . Builder ( schema )
. build ();
//keep the reference to GraphQL instance and execute queries against it.
//this operation selects a user by ID and requests name, regDate and twitterProfile fields only
ExecutionResult result = graphQL . execute (
"{ user (id: 123) {
name,
regDate,
twitterProfile {
handle
numberOfTweets
}
}}" );
我們正在研究SPQR驅動的彈簧靴啟動器。該項目還很年輕,但已經起作用。
在https://github.com/leangen/graphql-spqr-samples上查看更多完整的示例
即將推出
為了獲得最佳兼容性,編譯器參數-Xemit-jvm-type-annotations
需要Kotlin 1.3.70或更高版本。這指示Kotlin編譯器正確地產生類型使用註釋(在JDK8中引入)。有關詳細信息,請參見KT-35843和KT-13228。
在版本16 B17之前,OpenJDK的註釋解析器中有一個錯誤,該錯誤導致對通用類型參數的註釋被重複。您可能會以一種神秘的形式體驗到這一點
AnnotationFormatError: Duplicate annotation for class: interface io.leangen.graphql.annotations.GraphQLNonNull
在類型和其通用參數上使用@GraphQLNonNull
時被拋棄,例如@GraphQLNonNull List<@GraphQLNonNull Item>
。
幸運的是,即使在受影響的JDK上,很少有用戶似乎會遇到這個問題。請注意,Java編譯源的僅相關,而不是Java運行代碼。另請注意,Intellij Idea與自己的JDK捆綁在一起,因此在Idea中構建項目可能會導致此錯誤。如果您的IDE不同,則應配置IDE以使用系統Java。