forked from wildfly-extras/wildfly-graphql-feature-pack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new quickstart for smallrye graphql client
- Loading branch information
Showing
13 changed files
with
706 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# GraphQL Client quickstart | ||
|
||
## Prerequisites | ||
- JDK 1.8+ | ||
- Maven | ||
|
||
## Quickstart's compatibility with server-side quickstart | ||
This quickstart requires the server-side quickstart implementation to function properly. Instructions for deploying the feature pack on the server-side can be found in the server-side quickstart's [README](../quickstart/README.md). | ||
|
||
|
||
## Building and deployment | ||
|
||
The [main README](../README.md) contains information about the layers in this feature pack. You can use the `wildfly-maven-plugin` to build and run the server with the feature pack, and deploy the quickstart war. | ||
|
||
``` | ||
mvn wildfly:provision wildfly:dev | ||
``` | ||
|
||
|
||
## Functionality | ||
The quickstart-client.war application exposes various REST endpoints that demonstrate interacting with the server-side GraphQL API through the SmallRye GraphQL Client. | ||
The endpoints utilize both typesafe and dynamic client approaches. | ||
### Typesafe API | ||
|
||
The typesafe client functions like a MicroProfile REST Client but is tailored for GraphQL endpoints. To use it, you will need domain model classes that match the GraphQL schema. | ||
|
||
Think of a client instance as a proxy. You interact with it as you would a regular Java object, and it translates your calls into GraphQL operations. | ||
|
||
It directly handles domain classes, translating input and output data between Java objects and their representations in the GraphQL query language. | ||
#### Example | ||
|
||
Let's start by defining a domain class `Film` to represent the data we will be working with. | ||
```java | ||
package org.wildfly.extras.quickstart.microprofile.graphql.client; | ||
|
||
import java.time.LocalDate; | ||
|
||
public class Film { | ||
String title; | ||
Integer episodeID; | ||
String director; | ||
LocalDate releaseDate; | ||
String desc; | ||
} | ||
``` | ||
Next, create a GraphQL client API interface `FilmClientApi` to define the GraphQL operations: | ||
```java | ||
@GraphQLClientApi | ||
interface FilmClientApi { | ||
@Query | ||
List<Film> getAllFilms(); | ||
} | ||
``` | ||
|
||
Finally, implement a REST endpoint to expose the GraphQL client's functionality: | ||
```java | ||
@GET | ||
@Path("/typesafe/films") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public List<Film> getAllFilms() { | ||
FilmClientApi client = TypesafeGraphQLClientBuilder.newBuilder() | ||
.endpoint(url) // http://localhost:8080/quickstart/graphql | ||
.build(FilmClientApi.class); | ||
return client.getAllFilms(); | ||
} | ||
``` | ||
You can test the endpoint using a tool like curl: | ||
``` | ||
curl localhost:8080/quickstart-client/typesafe/films | ||
``` | ||
The typesafe client will automatically generate the corresponding GraphQL query based on the operation's return type and domain classes: | ||
``` | ||
query allFilms { | ||
allFilms { | ||
title | ||
pisodeID | ||
director | ||
releaseDate | ||
desc | ||
} | ||
} | ||
``` | ||
The proxy will then send this query as part of the GraphQL request to the server. The server will process the request and return a GraphQL response. | ||
The response will be deserialized into Java objects. | ||
|
||
Other endpoints: | ||
- **`localhost:8080/typesafe/films/{id}`:** Retrieves a specific film by its index. | ||
- **`localhost:8080/typesafe/delete/hero/{id}`:** Deletes a hero by its index. | ||
- **`localhost:8080/typesafe/heroes/{surname}`:** Retrieves a list of heroes with a specific surname. | ||
|
||
### Dynamic API | ||
Unlike the typesafe API, the dynamic client does not require a client API interface or domain classes. It operates directly with abstract representations of GraphQL documents, constructed using a domain-specific language (DSL). | ||
Exchanged objects are treated as abstract `JsonObject`, but can be converted to concrete model objects if necessary. | ||
#### Example | ||
```java | ||
@GET | ||
@Path("/dynamic/films/{id}") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Film getFilmDynamic(@PathParam("id") int id) throws ExecutionException, InterruptedException { | ||
try (VertxDynamicGraphQLClient dynamicGraphQLClient = | ||
(VertxDynamicGraphQLClient) new VertxDynamicGraphQLClientBuilder() | ||
.url(url) | ||
.build() | ||
) { | ||
|
||
Variable filmId = var("filmId", nonNull(ScalarType.GQL_INT)); | ||
|
||
Document query = document( | ||
operation("film", vars(filmId), | ||
field("film", args(arg("filmId", filmId)), | ||
field("title"), | ||
field("episodeID"), | ||
field("director"), | ||
field("releaseDate"), | ||
field("desc") | ||
) | ||
) | ||
); | ||
Response response = dynamicGraphQLClient.executeSync(query, Collections.singletonMap("filmId", id)); | ||
return response.getObject(Film.class, "film"); | ||
} | ||
} | ||
``` | ||
You can test the endpoint using a tool like curl: | ||
``` | ||
curl localhost:8080/quickstart-client/dynamic/films/{id} | ||
``` | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ Copyright 2020 Red Hat, Inc. | ||
~ | ||
~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
~ you may not use this file except in compliance with the License. | ||
~ You may obtain a copy of the License at | ||
~ | ||
~ http://www.apache.org/licenses/LICENSE-2.0 | ||
~ | ||
~ Unless required by applicable law or agreed to in writing, software | ||
~ distributed under the License is distributed on an "AS IS" BASIS, | ||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
~ See the License for the specific language governing permissions and | ||
~ limitations under the License. | ||
--> | ||
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<artifactId>wildfly-microprofile-graphql-parent</artifactId> | ||
<groupId>org.wildfly.extras.graphql</groupId> | ||
<version>2.4.1.Final-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>wildfly-microprofile-graphql-quickstart-client</artifactId> | ||
<version>2.4.1.Final-SNAPSHOT</version> | ||
<packaging>war</packaging> | ||
<name>WildFly MicroProfile GraphQL - Quickstart Client</name> | ||
<description>Quickstart for the WildFly implementation of MicroProfile GraphQL Client</description> | ||
|
||
<properties> | ||
<maven.deploy.skip>true</maven.deploy.skip> | ||
<compiler-plugin.version>3.13.0</compiler-plugin.version> | ||
<!-- these are only relevant for testing --> | ||
<jboss.dist>${project.basedir}/target/wildfly</jboss.dist> | ||
<jboss.home>${jboss.dist}</jboss.home> | ||
<!-- Where the testing WF instance will be bound. | ||
If the user has already started their WF instance for experimenting with the quickstart, it is most likely | ||
on 127.0.0.1, so let's try 127.0.0.2 to avoid clashing and run a separate instance. --> | ||
<node0>127.0.0.2</node0> | ||
</properties> | ||
|
||
<licenses> | ||
<license> | ||
<name>Apache License, Version 2.0</name> | ||
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url> | ||
<distribution>repo</distribution> | ||
</license> | ||
</licenses> | ||
|
||
<!-- just override dependencyManagement from parent because we don't want to exclude transitive deps | ||
--> | ||
<dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>io.smallrye</groupId> | ||
<artifactId>smallrye-graphql-client-api</artifactId> | ||
<version>${version.io.smallrye.graphql}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.smallrye</groupId> | ||
<artifactId>smallrye-graphql-client</artifactId> | ||
<version>${version.io.smallrye.graphql}</version> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.smallrye</groupId> | ||
<artifactId>smallrye-graphql-client-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.smallrye</groupId> | ||
<artifactId>smallrye-graphql-client-implementation-vertx</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<!-- <dependency>--> | ||
<!-- <groupId>io.smallrye</groupId>--> | ||
<!-- <artifactId>smallrye-graphql-client-model</artifactId>--> | ||
<!-- <version>${version.io.smallrye.graphql}</version>--> | ||
<!-- <scope>provided</scope>--> | ||
<!-- </dependency>--> | ||
<dependency> | ||
<groupId>org.eclipse.microprofile.graphql</groupId> | ||
<artifactId>microprofile-graphql-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>jakarta.ws.rs</groupId> | ||
<artifactId>jakarta.ws.rs-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<finalName>quickstart-client</finalName> | ||
<plugins> | ||
<plugin> | ||
<!-- To be able to deploy the app by doing mvn package wildfly:deploy --> | ||
<groupId>org.wildfly.plugins</groupId> | ||
<artifactId>wildfly-maven-plugin</artifactId> | ||
<configuration> | ||
<feature-packs> | ||
<feature-pack> | ||
<location>wildfly@maven(org.jboss.universe:community-universe):current#${version.org.wildfly}</location> | ||
</feature-pack> | ||
<feature-pack> | ||
<location>org.wildfly.extras.graphql:wildfly-microprofile-graphql-feature-pack:${project.version}</location> | ||
</feature-pack> | ||
</feature-packs> | ||
<layers> | ||
<layer>cloud-server</layer> | ||
<layer>jmx-remoting</layer> | ||
<layer>management</layer> | ||
<layer>microprofile-graphql</layer> | ||
<layer>micrometer</layer> | ||
<layer>microprofile-telemetry</layer> | ||
</layers> | ||
</configuration> | ||
</plugin> | ||
|
||
<!-- Prepare a WildFly distribution for testing. Only relevant for the tests. --> | ||
<plugin> | ||
<groupId>org.jboss.galleon</groupId> | ||
<artifactId>galleon-maven-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>server-provisioning</id> | ||
<goals> | ||
<goal>provision</goal> | ||
</goals> | ||
<phase>test-compile</phase> | ||
<configuration> | ||
<install-dir>${project.build.directory}/wildfly-test</install-dir> | ||
<record-state>false</record-state> | ||
<log-time>${galleon.log.time}</log-time> | ||
<plugin-options> | ||
<jboss-maven-dist/> | ||
<jboss-fork-embedded>${galleon.fork.embedded}</jboss-fork-embedded> | ||
<optional-packages>passive+</optional-packages> | ||
</plugin-options> | ||
<feature-packs> | ||
<feature-pack> | ||
<transitive>true</transitive> | ||
<groupId>org.wildfly</groupId> | ||
<artifactId>wildfly-galleon-pack</artifactId> | ||
<version>${version.org.wildfly}</version> | ||
<inherit-packages>false</inherit-packages> | ||
<inherit-configs>false</inherit-configs> | ||
</feature-pack> | ||
<feature-pack> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>wildfly-microprofile-graphql-feature-pack</artifactId> | ||
<version>${project.version}</version> | ||
<inherit-packages>false</inherit-packages> | ||
<inherit-configs>false</inherit-configs> | ||
</feature-pack> | ||
</feature-packs> | ||
<configurations> | ||
<config> | ||
<model>standalone</model> | ||
<name>standalone.xml</name> | ||
<layers> | ||
<layer>jaxrs-server</layer> | ||
<layer>jmx-remoting</layer> | ||
<layer>observability</layer> | ||
<!-- Layers from this FP --> | ||
<layer>microprofile-graphql</layer> | ||
<layer>micrometer</layer> | ||
<layer>microprofile-telemetry</layer> | ||
</layers> | ||
</config> | ||
</configurations> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<configuration> | ||
<systemPropertyVariables combine.children="append"> | ||
<jboss.install.dir>${project.build.directory}/wildfly-test</jboss.install.dir> | ||
<server.jvm.args>-Djboss.bind.address=${node0} -Djboss.bind.address.management=${node0} -Djboss.bind.address.unsecure=${node0}</server.jvm.args> | ||
<node0>${node0}</node0> | ||
</systemPropertyVariables> | ||
</configuration> | ||
</plugin> | ||
|
||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>${compiler-plugin.version}</version> | ||
<configuration> | ||
<compilerArgs> | ||
<arg>-parameters</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?xml version="1.0" ?> | ||
<!-- | ||
~ Copyright 2019 Red Hat, Inc. | ||
` ~ | ||
~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
~ you may not use this file except in compliance with the License. | ||
~ You may obtain a copy of the License at | ||
~ | ||
~ http://www.apache.org/licenses/LICENSE-2.0 | ||
~ | ||
~ Unless required by applicable law or agreed to in writing, software | ||
~ distributed under the License is distributed on an "AS IS" BASIS, | ||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
~ See the License for the specific language governing permissions and | ||
~ limitations under the License. | ||
--> | ||
|
||
|
||
<!-- | ||
USAGE: | ||
/path/to/galleon/bin/galleon.sh provision /path/to/this/provision.xml -dir=/path/to/created/wildfly/install/dir | ||
(note that `-dir` should have double hyphens, which don't work in XML comments!) | ||
--> | ||
<installation xmlns="urn:jboss:galleon:provisioning:3.0"> | ||
<feature-pack location="wildfly@maven(org.jboss.universe:community-universe):current#31.0.1.Final"> | ||
<default-configs inherit="false"/> | ||
<packages inherit="false"> | ||
<!-- If docs/licenses is desired, uncomment this line --> | ||
<include name="docs.licenses"/> | ||
</packages> | ||
</feature-pack> | ||
<feature-pack location="org.wildfly.extras.graphql:wildfly-microprofile-graphql-feature-pack:2.3.0.Final"> | ||
<default-configs inherit="false"/> | ||
<packages inherit="false"> | ||
<!-- If docs/licenses is desired, uncomment this line --> | ||
<include name="docs.licenses.merge"/> | ||
</packages> | ||
</feature-pack> | ||
<config model="standalone" name="standalone.xml"> | ||
<layers> | ||
<!-- The base server --> | ||
<include name="cloud-server"/> | ||
<include name="jmx-remoting"/> | ||
<include name="management"/> | ||
<!-- Layers from this FP --> | ||
<include name="microprofile-graphql"/> | ||
</layers> | ||
</config> | ||
<options> | ||
<option name="optional-packages" value="passive+"/> | ||
</options> | ||
</installation> | ||
|
Oops, something went wrong.