java graphql_如何立即启动GraphQL Java服务器并使其运行

雷逸仙
2023-12-01

java graphql

by Prithviraj Pawar

通过Prithviraj Pawar

如何立即启动GraphQL Java服务器并使其运行 (How to get your GraphQL Java server up and running in no time)

GraphQL is a query language for fetching data over the internet. Since its public announcement by Facebook in 2015, it has sparked interest in many minds. GraphQL has primarily been used in JavaScript. In fact, Facebook released the reference implementation for it in JavaScript (graphql-js).

GraphQL是用于通过Internet提取数据的查询语言。 自2015年Facebook公开宣布以来,它在许多人中引起了人们的兴趣。 GraphQL主要用于JavaScript。 实际上,Facebook在JavaScript( graphql-js )中发布了其参考实现。

But this blog post will focus on the development of the GraphQL server in Java. GraphQL-Java is the corresponding GraphQL implementation in Java, and it gets updates and version improvements almost every month. Features like instrumentation, asynchronous calls to the backend, the dataloader, directives, and many more make it a very interesting and powerful repository in Java.

但是此博客文章将重点介绍Java中GraphQL服务器的开发。 GraphQL-JavaJava中相应的GraphQL实现,它几乎每个月都有更新和版本改进。 诸如检测,后端异步调用,数据加载器,指令等功能使它成为Java中非常有趣且功能强大的存储库。

如何在springboot中构建GraphQL Java Server (How to build a GraphQL Java Server in springboot)

Let’s take the example of a magic school from the Harry Potter Universe. The magic school’s data is as follows:

让我们以哈利波特宇宙中的魔法学校为例。 魔术学校的数据如下:

Here the DataStores can be backend servers, or even Databases. A RESTful fetching will look like below.

在这里,数据存储可以是后端服务器,甚至是数据库。 RESTful获取将如下所示。

GET: /student?{parameters}GET: /House?{parameters}

Basically expose an interface for a service. Thus if Professors are added in the above model, then a new endpoint has to be opened and the client has to take multiple round trips. Also if the client wants nested data like Harry’s wand origin or Ron’s house color, then the API server has to call the backend twice. It will also result in some unwanted House and wand information.

基本上公开服务的接口。 因此,如果在上述模型中添加了Professor ,则必须打开一个新的端点,并且客户端必须进行多次往返。 另外,如果客户想要嵌套数据,例如Harry的魔杖 起源 要么 罗恩的房子颜色 那么API服务器必须调用后端两次。 这也将导致一些不需要的房屋和魔杖信息。

Enter GraphQL: GraphQL is a schema-driven approach to fetching data. It models the data as graphs, and you have to issue a query to fetch the data. It works like SQL, but for web objects. So, a graphQL query for Harry looks like:

输入GraphQL :GraphQL是一种由模式驱动的方法来获取数据。 它将数据建模为图形,并且您必须发出查询以获取数据。 它的工作方式类似于SQL,但适用于Web对象。 因此,针对Harry的graphQL查询看起来像:

query{Magic School{Student{namewand{origin}}}}

Before going into GraphQL, we need to setup a spring MVC. The easiest way to do this is SpringBootStarter. You can select your desired build automation tool . This gives a package of spring embedded Tomcat ready to run on port 8080. To test Tomcat, run:

在进入GraphQL之前,我们需要设置一个Spring MVC。 最简单的方法是SpringBootStarter 。 您可以选择所需的构建自动化工具。 这提供了一个准备好在端口8080上运行的spring嵌入式Tomcat软件包。要测试Tomcat,请运行:

$gradle clean build$java -jar ./build/libs/graphql-demo-0.0.1-SNAPSHOT.jar

By default, Gradle names your JAR “project_name-version-SNAPSHOT.jar”. Check http:localhost:8080 to see Tomcat running on port 8080.

默认情况下,Gradle将您的JAR命名为“ project_name-version-SNAPSHOT.jar”。 检查http:localhost:8080 查看Tomcat在端口8080上运行。

Let’s now add a GraphQL-Java dependency in our build.gradle.

现在让我们在build.gradle中添加一个GraphQL-Java依赖

dependencies {compile('com.graphql-java:graphql-java:{version}')compile group: 'org.json', name: 'json', version: '20170516'}

Add the current version as found in the mavenCentral repository. Currently, the latest version is 8.0. Also add org.json, which is a handy library as GraphQL handles the request-response in JSON.

添加在mavenCentral存储库中找到的当前版本。 当前,最新版本是8.0。 还添加org.json,这是一个方便的库,因为GraphQL处理JSON中的请求-响应。

As I mentioned earlier, GraphQL is a schema-driven language. It asks users to select objects in the query against the schema.

如前所述,GraphQL是一种模式驱动的语言。 它要求用户根据模式选择查询中的对象。

Let’s dive right in:

让我们潜入:

We have opened a /graphql interface for GraphQL POST requests. We need to create a schema for representing data.

我们打开了一个/ graphql GraphQL POST请求的接口 我们需要创建一个表示数据的模式。

  • SchemaGenerator parses the schema and creates an Abstract Syntax Tree with field names as the child nodes.

    SchemaGenerator解析模式,并创建一个以字段名称作为子节点的抽象语法树

  • Then the fields are assigned types by TypeDefinitionRegistry, for example Int, String, and so on. GraphQL has a nice Type system wherein we can have custom types in the schema including enum, interfaces, unions, Lists, and more.

    然后,通过TypeDefinitionRegistry为字段分配类型 例如Int,String等。 GraphQL有一个不错的Type系统,其中我们可以在模式中具有自定义类型,包括枚举,接口,联合,列表等。

  • Take a look at the RuntimeWiring() step where the field “MagicSchool” is mapped to “Hogwarts” by a StaticDataFetcher.

    看一看其中场“MagicSchool”由StaticDataFetcher映射为“霍格沃茨”的RuntimeWiring()步骤

  • Every field is backed up by a datafetcher, and it is the job of datafetcher to resolve the data and return to GraphQL.

    每个字段都由一个数据获取器备份数据获取器的任务是解析数据并返回到GraphQL。

  • Then GraphQL wires it with the defined schema names, whether it’s a nested map of lists or a generic Map. GraphQL does it as long as you define the proper schema.

    然后GraphQL将它与定义的模式名称关联起来,无论它是列表的嵌套映射还是通用Map。 只要定义适当的架构,GraphQL就会执行此操作。
  • After Sending this data to ExecutionInput, the GraphQL engine parses-> validates->fetches->executes the query and returns you a JSON output of the response using .toSpecifiation()

    将数据发送到ExecutionInput之后 ,GraphQL引擎解析-> validates-> fetches->执行查询,并使用.toSpeci fiation()返回响应的JSON输出。

Let’s issue a query using GraphiQL. Add this extension to your browser and set the endpoint.

让我们使用GraphiQL发出查询。 将此扩展添加到浏览器并设置端点。

Look how the shape of your query determines the shape of the response. The schema can be visualized neatly because of the introspective nature of GraphQL. This enables the Validation and Syntax checking of the schema automatically due to the Abstract Syntax Tree created while parsing the schema.

查看查询的形状如何确定响应的形状。 由于GraphQL具有自省性,因此可以清晰地看到该架构。 由于在解析架构时创建了“抽象语法树”,因此可以自动启用架构的“验证”和“语法”检查。

Let’s add some more fields in the schema. We’ll build a Schema Definition Language. Create a file named magicSchool.graphql.

让我们在架构中添加更多字段。 我们将构建模式定义语言 。 创建一个名为magicSchool.graphql的文件

type Query{magicSchool:MagicSchool}type MagicSchool{name: StringHeadMaster:Stringstudent:Student}type Student{name:Stringwand:Wandhouse:House}type House{name:Stringcolor:Stringpoints:Int}type Wand{name:Stringorigin:String}

Modify the schema source in the code and check the new schema in GraphiQL

修改代码中的模式源,并在GraphiQL中检查新模式

File schemaFile = loadSchema("magicSchool.graphql");TypeDefinitionRegistry typeRegistry=schemaParser.parse(schemaFile);

The runtimeWiring for the schema and fetchers changes significantly to include the other Types. Each type has its independent DataFetcher.

模式和提取程序的runtimeWiring进行了显着更改,以包括其他类型。 每种类型都有其独立的DataFetcher。

Here we have @Autowired all the fetchers to get us the data. Every GraphQL type is backed up by a type resolver (data fetcher). These resolvers are independent of each other and can have different sources. Every DataFetcher here has a DatafetchingEnvironment, which is an interface into the GraphQL query execution. It contains the query-arguments, context, executionId, field-specific parameters, and so on.

在这里,我们已经@Autowired所有提取程序来获取数据。 每个GraphQL类型都由类型解析器(数据获取器)备份。 这些解析器彼此独立,并且可以具有不同的来源。 这里的每个DataFetcher都有一个DatafetchingEnvironment,它是GraphQL查询执行的接口。 它包含查询参数 上下文 executionId 特定字段的参数,等等

Take a look at StudentFetcher and the Output of our query (ignore the Extensions):

看一下StudentFetcher和查询的输出(忽略扩展):

public DataFetcher getData() {    return environment -> {        Map<String, Object> student = new HashMap<>();        if ("1".equalsIgnoreCase(environment.getArgument("id"))) {            student.put("name", "Harry Potter");        }        return student;    };}

Reminds you of SQL, doesn’t it? Also see how Underfetching and Overfetching get eliminated, and the control of the data is all in the client’s hands. Now we can get Harry and Ron’s information neatly and in one call to the server!

让您想起了SQL,不是吗? 另请参阅UnderfetchingOverfetching如何被淘汰,而数据的控制是所有客户的手中。 现在,我们可以通过一次调用服务器的方式,整齐地获取Harry和Ron的信息!

GraphQL执行策略和工具 (GraphQL Execution Strategy and Instrumentation)

Each query execution is Asynchronous in graphql-java. When you call build.execute(executionInput), it returns a CompletableFuture object which gets completed when the query completes its flow of execution.

每个查询执行在graphql-java中都是异步的。 当您调用build.execute(executionInput)时 它将返回CompletableFuture对象,当查询完成其执行流程时该对象将完成。

Also, as the fields are resolved separately, in the above example the Wand and House information are fetched and executed in parallel. The default ExecutionStrategy uses Java’s fork-join pool, but you can add your custom threadpool using the Executor Class.

另外,由于字段是分别解析的,因此在上面的示例中, 魔杖房屋信息被并行获取和执行。 默认的ExecutionStrategy使用Java的fork-join池,但是您可以使用Executor类添加自定义线程池。

ExecutorService executorService = new ThreadPoolExecutor(            128, /* core pool size 128 threads */            256, /* max pool size 256 threads */            10, TimeUnit.SECONDS,            new LinkedBlockingQueue<Runnable>(),            new ThreadPoolExecutor.CallerRunsPolicy());    return GraphQL.newGraphQL()            .instrumentation(new TracingInstrumentation ())             .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(executorService))            .build();}

graphql-java allows you to instrument the query execution at every point: beforeExecution, beforeParsing, and beforeFetching. You can extend the Instrumentation class and provide your own action at each step — for example, logging the queries and returning the time of each step.

graphql-Java允许你在仪器的每一个点的查询执行:beforeExecution,beforeParsing beforeFetching 您可以扩展Instrumentation类,并在每个步骤中提供自己的操作-例如,记录查询并返回每个步骤的时间。

The instrumentation output provides an extensions map in Apollo Tracing format by default. This can later be used by a certain client to visualize the execution data (for example, using elastic-search and Grafana). Now you know what the extensions in the above picture mean!

仪器输出默认情况下以Apollo跟踪格式提供扩展映射。 稍后,某些客户端可以使用它来可视化执行数据(例如,使用elastic-search和Grafana)。 现在您知道了上图中的扩展名是什么意思!

The complete code of the above example can be accessed from here.

可以从此处访问以上示例的完整代码。

结语 (Wrapping up)

There are many more features in graphql-java, like Dataloader (which solves the N+1 fetching problem), directives (which make schema writing easier), and so on. GraphQL is an emerging technology that makes the client’s life easier and can change how we do things on the Internet. That is why many companies like Facebook, Twitter, GitHub, and Coursera have already adopted it.

graphql-java中还有许多其他功能,例如Dataloader (解决了N + 1提取问题), 指令 (使架构编写更容易)等等。 GraphQL是一项新兴技术,可以使客户的生活更轻松,并可改变我们在Internet上的处理方式。 这就是为什么像Facebook,Twitter,GitHub和Coursera这样的许多公司已经采用了它的原因。

I would love to hear your comments about GraphQL. Please share your views. Also if you like the blog post, don’t forget to clap.

我希望听到您对GraphQL的评论。 请分享您的看法。 另外,如果您喜欢博客文章,请别忘了鼓掌。

翻译自: https://www.freecodecamp.org/news/graphql-java-development-stack-in-production-21f402c4c37a/

java graphql

 类似资料: