This is an example of the MicroProfile GraphQL API using the SmallRye Implementation. It's done as part of these blog posts:
and these presentations:
The services are exposed with both REST and GraphQL for comparison.
This example expose person data as well as scores that the person got for certain activities.
(generate from https://code.quarkus.io/)
cd quarkus-example
mvn clean install quarkus:dev
cd wildfly-example
mvn clean install wildfly:run
This will start the application on port 8080.
Go to http://localhost:8080 to test the application.
To stop the application, ctrl-c
in the maven session.
See the model in the JavaDoc (target/apidocs/index.html)
Schema: http://localhost:8080/openapi
curl -X GET "http://localhost:8080/rest/profile/1" -H "accept: application/json"
Schema: http://localhost:8080/graphql/schema.graphql
{
person(id:1){
names
surname
}
}
{
person(id:1){
names
surname
scores{
name
value
}
}
}
in the log file:
======= Getting person [1] =======
======= Getting scores [512-46-5065] =======
without score
{
person(id:1){
names
surname
}
}
in the log file:
======= Getting person [1] =======
{
people{
names
scores{
name
}
}
}
in the log file:
======= Getting scores [797-95-4822, 373-95-3047, 097-87-6795, 347-01-8880, 733-86-4423, 560-99-2165, 091-07-5401, 539-70-2014, 029-18-5986, 287-58-0690] =======
{
person1:person(id:1){
surname
scores{
name
value
}
}
person2:person(id:2){
surname
}
}
or more than one query:
@Query
public Integer getRandomNumber(long seed){
Random random = new Random(seed);
return random.nextInt();
}
{
person1:person(id:1){
surname
scores{
name
value
}
}
randomId:randomNumber(seed:11)
}
{
people {
surname
}
}
{
person(id:1){
surname
birthDate
}
}
@Query
public List<Person> getPersonsWithSurname(
@DefaultValue("Doyle") String surname) {
return personService.getPeopleWithSurname(surname);
}
Providing a parameter
{
personsWithSurname(surname:"Hyatt") {
names
}
}
Uing the default
{
personsWithSurname {
names
}
}
{
person(id:1){
surname
scores{
thisDoesNotExist
}
}
}
{
person(id:1){
surname
scores{
name
value
}
}
}
This will be specific to your setup. For me:
Start Prometheus:
cd /opt/Metrics/prometheus-2.19.2.linux-amd64
./prometheus --config.file=prometheus.yml
(prometheus.yml is in the root folder)
Start Grafana:
sudo systemctl start grafana-server
(grafana.json is in the root folder)
Start Jaeger:
docker run -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 jaegertracing/all-in-one:latest
@Timed(name = "personTimer", description = "How long does it take to get a Person.", unit = MetricUnits.NANOSECONDS)
@Counted(name = "personCount", description = "How many times did we ask for Person.")
@RolesAllowed("admin")
@Query
public Integer getRandomNumber(@Min(10) long seed){
Random random = new Random(seed);
return random.nextInt();
}
{
randomNumber(seed:9)
}
@Mutation
public Person updatePerson(Person person){
return personService.updateOrCreate(person);
}
@Mutation
public Person deletePerson(Long id){
return personService.delete(id);
}
mutation CreatePerson{
updatePerson(person :
{
names: "Phillip"
}
){
id
names
surname
profilePictures
website
}
}
(using the generated id)
mutation UpdatePerson{
updatePerson(person :
{
id: 11,
names:"Phillip",
surname: "Kruger",
profilePictures: [
"https://pbs.twimg.com/profile_images/1170690050524405762/I8KJ_hF4_400x400.jpg"
],
website: "http://www.phillip-kruger.com"
}){
id
names
surname
profilePictures
website
}
}
(using the id)
mutation DeletePerson{
deletePerson(id :11){
id
surname
}
}
quarkus.hibernate-orm.log.sql=true
@Inject
Context context;
JsonArray selectedFields = context.getSelectedFields();
System.out.println("selectedFields [" + selectedFields +"]");
{
people{
surname
}
}
See the model in the JavaDoc (target/apidocs/index.html)
//@Inject
PersonGraphQLClient graphQLClient = GraphQlClientBuilder.newBuilder().build(PersonGraphQLClient.class);
Person graphQLPerson = graphQLClient.getPerson(id);
System.err.println("================ GRAPHQL ================");
System.err.println(graphQLPerson);
{
__schema{
types {
name
kind
}
}
}
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
subscriptionType { name }
types {
...FullType
}
directives {
name
description
locations
args {
...InputValue
}
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
...InputValue
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
...InputValue
}
interfaces {
...TypeRef
}
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
possibleTypes {
...TypeRef
}
}
fragment InputValue on __InputValue {
name
description
type { ...TypeRef }
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
}
}
}
}