com.daikit:spring-data-graphql-jpa-demo

Demo project for java-data-graphql and spring-boot-starter-data-graphql-jpa.

License

License

Categories

Categories

Data
GroupId

GroupId

com.daikit
ArtifactId

ArtifactId

spring-data-graphql-jpa-demo
Last Version

Last Version

1.2
Release Date

Release Date

Type

Type

jar
Description

Description

com.daikit:spring-data-graphql-jpa-demo
Demo project for java-data-graphql and spring-boot-starter-data-graphql-jpa.
Project URL

Project URL

https://github.com/tcaselli/spring-data-graphql-jpa-demo
Source Code Management

Source Code Management

https://github.com/tcaselli/spring-data-graphql-jpa-demo

Download spring-data-graphql-jpa-demo

How to add to project

<!-- https://jarcasting.com/artifacts/com.daikit/spring-data-graphql-jpa-demo/ -->
<dependency>
    <groupId>com.daikit</groupId>
    <artifactId>spring-data-graphql-jpa-demo</artifactId>
    <version>1.2</version>
</dependency>
// https://jarcasting.com/artifacts/com.daikit/spring-data-graphql-jpa-demo/
implementation 'com.daikit:spring-data-graphql-jpa-demo:1.2'
// https://jarcasting.com/artifacts/com.daikit/spring-data-graphql-jpa-demo/
implementation ("com.daikit:spring-data-graphql-jpa-demo:1.2")
'com.daikit:spring-data-graphql-jpa-demo:jar:1.2'
<dependency org="com.daikit" name="spring-data-graphql-jpa-demo" rev="1.2">
  <artifact name="spring-data-graphql-jpa-demo" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.daikit', module='spring-data-graphql-jpa-demo', version='1.2')
)
libraryDependencies += "com.daikit" % "spring-data-graphql-jpa-demo" % "1.2"
[com.daikit/spring-data-graphql-jpa-demo "1.2"]

Dependencies

compile (4)

Group / Artifact Type Version
.com.daikit » spring-boot-starter-data-graphql-jpa jar 1.2
org.springframework.boot : spring-boot-starter-log4j2 jar 2.0.4.RELEASE
org.apache.logging.log4j : log4j-slf4j-impl jar
org.apache.logging.log4j : log4j-web jar

runtime (1)

Group / Artifact Type Version
com.h2database : h2 jar 1.4.197

test (1)

Group / Artifact Type Version
org.springframework.boot : spring-boot-starter-test jar 2.0.4.RELEASE

Project Modules

There are no modules declared in this project.

Spring data GraphQL JPA Demo

License

Documentation

This spring-data-graphql-jpa-demo project is intended to provide an easy to understand usage showcase of java-data-graphql together with spring-boot-starter-data-graphql-jpa.

The java-data-graphql library is a layer above the great graphql-java library. It generates a graphql schema out of a given configuration which grants the possibility to :

  • execute CRUD operations on entities (getById, getAll, save, delete).
  • deal with persisted entities and embedded data objects.
  • handle dynamic attributes on any entity.
  • add custom methods (queries or mutations) to enrich your schema.
  • deal with paging, sorting, filtering on queries.
  • easily create "data fetchers" for linking this library to the persistence layer of your choice.

This demo project is a showcase of the usage of this library together together with a JPA persistence layer. GraphQL queries and mutations will be automatically converted to database SQL queries.

How to launch the demo

First, checkout the code from github.

-> From command line

mvn install
# Replace XXX with current version (example : XXX = 1.1-SNAPSHOT)
java -jar target/spring-data-graphql-jpa-demo-XXX.jar

-> From your IDE

Run com.daikit.graphql.spring.jpa.demo.ApplicationStarter as a Java application

How to browse the demo

You are now able to browse your schema with graphiql web user interface available at http://localhost:8080/graphiql/index.html

Graphiql web UI

You can run queries and mutations with variables. See next section for samples.

Graphiql web UI query

Sample queries and mutations

You can run these sample queries and mutations in graphiql. Variables are to be set in lower left area of the user interface.

Get entity by ID

# query
query getEntity1($id: ID!) {
  getEntity1(id: $id) {
    id
    intAttr
    longAttr
    stringAttr
    embeddedData1 {
      stringAttr
    }
  }
}
# variables
{
    "id":"3"
}

Get list of entities

# query retrieving all entities
query getAllEntity5 {
  getAllEntity5 {
    data {
        id
        intAttr
        stringAttr
    }
  }
}

# query with paging
query getAllEntity5 {
  getAllEntity5(
    paging: { limit: 2, offset: 1 }
  ) {
    data {
        id
        intAttr
        stringAttr
    }
  }
}

# query with ordering
query getAllEntity5 {
  getAllEntity5(
    orderBy: [
        { field: "intAttr", direction: DESC },
        { field: "stringAttr", direction: DESC }
    ]
  ) {
    data {
        id
        intAttr
        stringAttr
    }
  }
}

# query with filtering
# /!\ Filtering only works on int and String types.. 
# filtering on other types has not been implemented in this demo
query getAllEntity5 {
  getAllEntity5(
    filter: { 
        intAttr: { operator: le, value: 5 },
        stringAttr: { operator: endsWith, value: "-4" }
    }
  ) {
    data {
        id
        intAttr
        stringAttr
    }
  }
}

Save entity

# mutation
mutation saveEntity1($id: ID, $intAttr: Int, $embeddedData1: EmbeddedData1InputType) {
  saveEntity1(data: { id: $id, intAttr: $intAttr, embeddedData1: $embeddedData1}) {
    id
    intAttr
    embeddedData1 {
      stringAttr
    }
  }
}
# variables
{
    "id": "3",
    "intAttr": 150,
    "embeddedData1": {
        "stringAttr": "test data1"
    }
}

Delete entity

# mutation
mutation deleteEntity1($id: ID!) {
  deleteEntity1(id: $id) {
    id
    typename
  }
}
# variables
{
    "id": "2"
}

Custom method mutation

# mutation
mutation customMethodMutation1($arg1: String) {
    customMethodMutation1(arg1: $arg1) {
        stringAttr
    }
}
# variables
{
    "arg1": "This value should be returned"
}

Custom method query

# query
query customMethodQuery1($arg1: String) {
    customMethodQuery1(arg1: $arg1) {
        intAttr
        stringAttr
        embeddedData1 {
            stringAttr
        }
    }
}
# variables
{
    "arg1": "This string is set in both returned stringAttr"
}
# query
query customMethodQuery2(
    $arg1: String, 
    $arg2: EmbeddedData1InputType
) {
    customMethodQuery2(arg1: $arg1, arg2: $arg2) {
        intAttr
        stringAttr
        embeddedData1 {
            intAttr
            stringAttr
        }
    }
}
# variables
{
    "arg1": "This string is set in returned stringAttr",
    "arg2": {
        "intAttr": 2,
        "stringAttr": "This string is set in returned embeddedData1"
    }
}
# query
query customMethodQuery3(
    $arg1: Enum1, 
    $arg2: [String], 
    $arg3: [Enum1], 
    $arg4: [EmbeddedData1InputType], 
    $arg5: String
) {
    customMethodQuery3(
        arg1: $arg1, 
        arg2: $arg2, 
        arg3: $arg3, 
        arg4: $arg4, 
        arg5: $arg5
    ) {
    enumAttr
    stringList
    enumList
    embeddedData1s {
        stringAttr
    }
    stringAttr
  }
}
# variables
{
    "arg1": "VAL2",
    "arg2": ["string1", "string2"],
    "arg3": ["VAL1", "VAL2"],
    "arg4": [{"stringAttr": "data1"}, {"stringAttr": "data2"}],
    "arg5": null
}
# TIP : there is a check on arg5:
# -> if null the set "NULLVALUE" otherwise set as null

Dynamic attribute getter

# query
query getEntity1($id: ID!) {
  getEntity1(id: $id) {
    id
    dynamicAttribute1
  }
}
# variables
{
    "id": "3"
}

Dynamic attribute setter

# mutation
mutation saveEntity1($id: ID, $dynamicAttribute2: String) {
  saveEntity1(data: { id: $id, dynamicAttribute2: $dynamicAttribute2 }) {
    id
    stringAttr
  }
}
# variables
{
    "id": "3",
    "dynamicAttribute2": "This string is set in stringAttr"
}

Architecture overview

QueryDSL entity paths

In order to be able to automatically convert GraphQL queries to JPA queries, all entities referenced in GraphQL schema must have a corresponding queryDSL entityPath.
These entityPaths are generated thanks to apt-maven-plugin.

Spring data JPA repositories

In order to be able to automatically convert GraphQL queries to JPA queries, all entities referenced in GraphQL schema have a corresponding spring data repository interface extending com.daikit.graphql.spring.jpa.repository.IEntityRepository.

The entity service

The entity service (extending com.daikit.graphql.spring.jpa.service.IEntityService) is providing methods accessible by GraphQL data fetchers for CRUD operations on any entity types. Default implementation com.daikit.graphql.spring.jpa.service.DefaultEntityService is used in this demo, feel free to override it.

Custom hibernate user types

When you want to store data as JSON in a SQL column you need to use hibernate custom org.hibernate.usertype.UserType. These data can then be available in the GraphQL layer thanks to "embedded entities" (set the entity meta data as embedded when building the GraphQL meta model).
Some custom user types have been defined in this project, see com.daikit.graphql.spring.jpa.demo.usertype.impl package content for examples.

Contributing

We accept Pull Requests via GitHub. There are some guidelines which will make applying PRs easier for us:

  • No spaces :) Please use tabs for indentation.
  • Respect the code style.
  • Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.

License

This code is under the Apache Licence v2.

Versions

Version
1.2
1.1
1.0