DEV Community

Cover image for GraphQL Codegen adds new Apollo-Android and Java plugins
TheGuildBot for The Guild

Posted on • Updated on • Originally published at the-guild.dev

GraphQL Codegen adds new Apollo-Android and Java plugins

This article was published on Wednesday, June 19, 2019 by Dotan Simha @ The Guild Blog

As you probably already know, GraphQL Code Generator has
become the most popular GraphQL code generation tool in the community.

We constantly improve the underlying tools and also create more generators and plugins.

One thing that some people often miss about GraphQL Code Generator, is that its programming language
agnostic.

We have many plugins from the community to generate different language outputs like C#, ReasonML,
Dart and others.

But today we want to announce something new — we now have 2 new official plugins for Java.

A Apollo-Android generator and a
Java backend resolvers signature
generator.

We've created those plugins because we needed them for some of our clients' production applications
and the current tools in the ecosystem that are currently out there weren't sufficient enough for
us.

Apollo-Android

The new plugin allows you to generate Java code if your project is using Apollo-Android.

It includes a query builder and a response builders (for converting the network response into a
type-safe classes), and it integrates with Apollo-Android runtime.

The goal of the generated code is to let you use your GraphQL operations (query, mutation,
subscription and fragment) without the need to convert JSONs or deal with HTTP requests — you
just need to write your operations, run the codegen and you'll get ready-to-use Java classes.

The reason we decided to implement our own plugin was because now that we need to use it in large
production apps, the current tools in the ecosystem weren't sufficient enough for us.

We also think this is a good opportunity for the community to iterate faster because of all the
awesome capabilities the generator already has.

Using the GraphQL Code Generator infrastructure, we make sure that customization of the generated
code will be much easier, and fixing bugs and adding features will be simpler and faster.

It also makes it much easier to load your schema from everywhere (either from a url, local file,
introspection, or directly from code files containing strings), customize your GraphQL Scalars and
map them to Java types, customize the names of the generated classes, the output path and more.

The new plugin will be available today in beta using the following tag — 1.2.2-beta.01.

How to Try It Now?

Next week we are also planning to make it easier to integrate the plugin by building a Gradle plugin
that wraps the execution of the Codegen, and integrates it with the Java ecosystem.

On the stable release this Gradle plugin will be available, but for now, if you wish to try it now,
you'll need to configure it manually.

Because the current GraphQL Code Generator package is released on NPM, you'll need to create a
simple package.json file with the following content:

{
  "name": "java-app",
  "scripts": {
    "postinstall": "graphql-codegen"
  },
  "dependencies": {
    "graphql": "15.0.0",
    "@graphql-codegen/cli": "1.14.0",
    "@graphql-codegen/java-apollo-android": "1.14.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Next, create the codegen.yml config file with the following content:

schema: 'schema.graphql'
documents: './src/main/**/*.graphql'
generates:
  generatedJava/:
    preset: 'java-apollo-android'
    config:
      package: 'com.app.generated.graphql'
    plugins:
      - 'java-apollo-android'
Enter fullscreen mode Exit fullscreen mode

You can use your GraphQL endpoint if your schema is not available locally.

Next, you need to configure your Gradle build configuration by adding the following dependency to
your build.gradle:

plugins {
  id "com.moowork.node" version "1.3.1"
}
Enter fullscreen mode Exit fullscreen mode

Also, add a build step:

build.dependsOn yarn
Enter fullscreen mode Exit fullscreen mode

Now, when you'll run your Gradle build, it will make sure to download the Codegen and it's plugins,
and will generate the Java classes for you.

The usage of the generated code is the same you had before, just follow
the instructions of Apollo-Android runtime.

Java Backend Resolver Plugin

The other plugin generates resolvers signature, that allow you to integrate your Java models classes
to the generated signature, so you'll get a type-safe implementation of your resolvers.

It's based on graphql-java and compatible with its implementation for
DataFetchers.

Follow the instructions above, but use this package.json:

{
  "name": "java-app",
  "scripts": {
    "postinstall": "graphql-codegen"
  },
  "dependencies": {
    "graphql": "15.0.0",
    "@graphql-codegen/cli": "1.14.0",
    "@graphql-codegen/java-resolvers": "1.14.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Then, for the following schema:

type Query {
  me: User!
}

interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  username: String!
  email: String!
  name: String
}

type Chat implements Node {
  id: ID!
  users: [User!]!
  title: String
}

union SearchResult = Chat | User
Enter fullscreen mode Exit fullscreen mode

And the following codegen.yml configuration, that maps your GraphQ types into your Java models:

schema: 'src/app/resources/schema.graphql'
generates:
  src/app/graphql/generated/Resolvers.java:
    plugins:
      - java-resolvers
    config:
      mappers:
        User: 'com.myapp.models.UserModel#UserModel'
        Chat: 'com.myapp.models.ChatModel#ChatModel'
        Node: 'com.myapp.models.BaseModel#BaseModel'
Enter fullscreen mode Exit fullscreen mode

You'll get a complete type-safe resolvers signature:

package com.java.generated;

import com.myapp.models.UserModel;
import com.myapp.models.ChatModel;
import com.myapp.models.BaseModel;
import graphql.schema.TypeResolver;
import graphql.schema.DataFetcher;

public class Resolvers {
  public interface Chat {
    public DataFetcher<Object> id();
    public DataFetcher<Iterable<UserModel>> users();
    public DataFetcher<String> title();
  }

  public interface Node extends TypeResolver {
    default public DataFetcher<Object> id() { return null; }
  }

  public interface Query {
    public DataFetcher<UserModel> me();
    public DataFetcher<Iterable<ChatModel>> chats();
    public DataFetcher<Iterable<Object>> search();
  }

  public interface SearchResult extends TypeResolver {}

  public interface User {
    public DataFetcher<Object> id();
    public DataFetcher<String> username();
    public DataFetcher<String> email();
    public DataFetcher<String> name();
  }

}
Enter fullscreen mode Exit fullscreen mode

Now you can use it as base interface for your DataFetcher implementation, and get a type-safe
resolvers!

What's Next?

We are getting close to a stable release for those plugins and want your opinions on them.

As mentioned, the stable release will also include a Gradle plugin to make it easier to integrate
the Codegen with the Java ecosystem.

Please try it out today, and send us a feedback. Our goal is to make this plugin easy to use, and
easy to customize, and you would see how quickly we manage, respond and solve issues on our open
source tools, which is something we are very proud of.

Top comments (0)