A Quick Start Guide to Getting a Java GraphQL API up and Running in no time Using Apifi.
Apifi is a Java (8+) annotation processing framework which auto generates GraphQL APIs for JPA based data models. It spans the full API stack; from data access to client side consumption. Apifi is centered around one simple goal: To eliminate the need for generic CRUD related boilerplate without compromising on control and customizability.
This means no service beans implementing generic CRUD logic, no manual GraphQL setup, no JpaRepositories, no web controller. All of that’s taken care of. You just focus on what makes your project unique, no boilerplate required.
TLDR; Apifi can instantly turn any JPA data model into a GraphQL API, no boilerplate code required.
In this article we’ll be demonstrating how to rapidly build a simple eCommerce Java GraphQL API using Apifi and Spring Boot. Before we start I’ll just note that Apifi is built on top of graphql-java, SPQR, and Spring Data JPA. You’ll probably be able to understand this guide regardless, but I’d strongly recommend being at least somewhat familiar with these tools in order to understand what’s actually going on under the hood.
<dependencies>
<dependency>
<groupId>dev.sanda</groupId>
<artifactId>apifi</artifactId>
<version>0.0.5.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
The eCommerce API needs to be able to:
The data model consists of 4 classes:
Customer
Product
Archivable is an interface defined within Apifi containing two methods:
Boolean getIsArchived();
void setIsArchived(Boolean isArchived);
This allows us (and Apifi) to mark objects as archived instead of full-on deleting them from the database. This will come in handy when we implement the customer checkout logic and want to keep track of ordered products after removing (i.e. archiving) the sold items.
ShoppingCart
CustomerOrder
Note the @Transient ShoppingCart “fromCart” field in CustomerOrder. Transient fields exist in memory only and are not included in the database schema. We’ll demonstrate why this one is here a bit further down.
In order to turn this data model into a fully functional GraphQL API, we just need to add a few annotations. The first annotation which we’ll see as applied to the Customer class is
@WithCrudEndpoints(...)
:This annotation allows us to define GraphQL queries and mutations with respect to the annotated class. In this case:
createCustomer ( input CustomerInput ) Customer
customerById ( input Long ) Customer
Next, we’ll use the same annotation on the Product class to define a
createProducts ( input [ProductInput] ) [Product]
mutation:
Next up is ShoppingCart. We’ll be using the @EntityCollectionApi(...) annotation this time:
This annotation allows us to define GraphQL queries and mutations with respect to the annotated Collection type field. In this case:
The associatePreExistingOnly = true flag denotes that only preexisting Product objects are allowed as input to the associateProductsWithShoppingCart mutation (This makes sense in our case — you can’t add products to a shopping cart if they’re not already in the inventory). If a non existent Product object were to be passed to the associateProductsWithShoppingCart mutation an exception would be thrown, terminating and rolling back the operation.
Last but not least, customers need to check out and complete their purchase after filling up their shopping carts. To do this, we’ll once again use the
@WithCrudEndpoints(...)
annotation:This will create a
createCustomerOrder ( input CustomerOrderInput ) CustomerOrder
mutation.
The only requirement now left to complete is the customer checkout logic. As briefly mentioned above, when a customer checks out by creating a new CustomerOrder, the following should happen:
In order to apply the required logic to the createCustomerOrder mutation, we create a bean class which we’ll call CustomerOrderApiHooks. This class will implement the ApiHooks<CustomerOrder> interface, and override the preCreate method. ApiHooks is an interface we can implement in order to inject custom logic before and after CRUD operations.
CustomerOrderApiHooks
And that’s it, all that’s left now is to see it in action:
If you've made it this far kudos to you and thanks for reading!
Also published behind a paywall at: https://medium.com/swlh/instantly-deploy-java-graphql-apis-using-apifi-quick-start-eb2406f6859