Giter Site home page Giter Site logo

justtonytone / apollo-android Goto Github PK

View Code? Open in Web Editor NEW

This project forked from apollographql/apollo-kotlin

0.0 0.0 0.0 140.68 MB

:pager: A strongly-typed, caching GraphQL client for Android and the JVM

License: MIT License

Kotlin 32.04% Java 65.90% Groovy 1.86% Shell 0.07% ANTLR 0.12%

apollo-android's Introduction

Apollo GraphQL Client for Android and the JVM

GitHub license Join Spectrum Build status GitHub release

Apollo-Android is a GraphQL compliant client that generates Java and Kotlin models from standard GraphQL queries. These models give you a typesafe API to work with GraphQL servers. Apollo will help you keep your GraphQL query statements together, organized, and easy to access. Change a query and recompile your project - Apollo code gen will rebuild your data model. Code generation also allows Apollo to read and unmarshal responses from the network without the need of any reflection.

Apollo-Android is designed primarily with Android in mind but you can use it in any Java/Kotlin app. The android-only parts are in apollo-android-support and are only needed to use SQLite as a cache or the android main thread for callbacks.

Apollo-android features:

  • Automatic generation of typesafe models.
  • Support for Java and Kotlin code generation.
  • Queries, Mutations and Subscriptions.
  • Reflection-free parsing of responses.
  • HTTP cache.
  • Normalized cache.
  • File Upload.
  • Custom scalar types.
  • Support for RxJava2 and Coroutines.

Adding Apollo-Android to your Project

The latest Gradle plugin version is Download

To use this plugin, add the dependency to your project's root build.gradle file:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath("com.apollographql.apollo:apollo-gradle-plugin:x.y.z")
  }
}

Then add the dependencies to your app's build.gradle and apply file and apply the com.apollographql.apollo plugin:

apply plugin: 'com.apollographql.apollo'

repositories {
    jcenter()
}

dependencies {
  implementation("com.apollographql.apollo:apollo-runtime:x.y.z")
  
  // If not already on your classpath, you might need the jetbrains annotations
  compileOnly("org.jetbrains:annotations:13.0")
  testCompileOnly("org.jetbrains:annotations:13.0")
}

Generating models from your queries

  1. Create a directory for your GraphQL files like you would do for Java/Kotlin: src/main/graphql/com/example/. Apollo-Android will generate models in the com.apollographql.apollo.sample package.
  2. Add your schema.json to the directory at src/main/graphql/com/example/schema.json. If you don't have a schema.json file yet, read the section about downloading a schema file.
  3. Put your GraphQL queries in a .graphql files. For an example: src/main/graphql/com/example/feed.graphql:
query FeedQuery($type: FeedType!, $limit: Int!) {
  feed(type: $type, limit: $limit) {
    comments {
      ...FeedCommentFragment
    }
    repository {
      ...RepositoryFragment
    }
    postedBy {
      login
    }
  }
}

fragment RepositoryFragment on Repository {
  name
  full_name
  owner {
    login
  }
}

fragment FeedCommentFragment on Comment {
  id
  postedBy {
    login
  }
  content
}
  1. Decide if you want to generate Kotlin or Java models:
// build.gradle or build.gradle.kts
apollo {
  generateKotlinModels.set(true) // or false for Java models
}
  1. Execute ./gradlew generateApolloClasses to generate the models from your queries. This will create a generated FeedQuery Java or Kotlin source file for your query.

Consuming Code

Apollo includes an ApolloClient to interact with your server and cache.

To make a query using the generated models:

apolloClient.query(
  FeedQuery.builder()
    .limit(10)
    .type(FeedType.HOT)
    .build()
).enqueue(new ApolloCall.Callback<FeedQuery.Data>() {

  @Override public void onResponse(@NotNull Response<FeedQuery.Data> dataResponse) {

    final StringBuffer buffer = new StringBuffer();
    for (FeedQuery.Data.Feed feed : dataResponse.data().feed()) {
      buffer.append("name:" + feed.repository().fragments().repositoryFragment().name());
().login());
      buffer.append(" postedBy: " + feed.postedBy().login());
    }

    // onResponse returns on a background thread. If you want to make UI updates make sure they are done on the Main Thread.
    MainActivity.this.runOnUiThread(new Runnable() {
      @Override public void run() {
        TextView txtResponse = (TextView) findViewById(R.id.txtResponse);
        txtResponse.setText(buffer.toString());
      }
    });
      
  }

  @Override public void onFailure(@NotNull Throwable t) {
    Log.e(TAG, t.getMessage(), t);
  }
});       

Custom Scalar Types

Apollo supports Custom Scalar Types like Date.

You first need to define the mapping in your build.gradle file. This maps from the GraphQL type to the Java/Kotlin class to use in code.

apollo {
  customTypeMapping = [
    "Date" : "java.util.Date"
  ]
}

Next register your custom adapter & add it to your Apollo Client Builder:

 dateCustomTypeAdapter = new CustomTypeAdapter<Date>() {
      @Override public Date decode(CustomTypeValue value) {
        try {
          return DATE_FORMAT.parse(value.value.toString());
        } catch (ParseException e) {
          throw new RuntimeException(e);
        }
      }

      @Override public CustomTypeValue encode(Date value) {
        return new CustomTypeValue.GraphQLString(DATE_FORMAT.format(value));
      }
    };

ApolloClient.builder()
  .serverUrl(serverUrl)
  .okHttpClient(okHttpClient)
  .addCustomTypeAdapter(CustomType.DATE, dateCustomTypeAdapter)
  .build();

If you have compiler warnings as errors (options.compilerArgs << "-Xlint" << "-Werror") turned on, your custom type will not compile. You can add a switch suppressRawTypesWarning to the apollo plugin configuration which will annotate your generated class with the proper suppression (@SuppressWarnings("rawtypes"):

apollo {
    customTypeMapping = [
      "URL" : "java.lang.String"
    ]
    suppressRawTypesWarning = "true"
}

Downloading a schema.json file

You can get a schema.json file by running an introspection query on your endpoint. The Apollo Gradle plugin exposes a downloadApolloSchema task to help with this. You can download a schema by specifying your endpoint and the location where you want the schema to be downloaded:

./gradlew :shared:downloadApolloSchema -Pcom.apollographql.apollo.endpoint=https://your.graphql.endpoint -Pcom.apollographql.apollo.schema=src/main/graphql/com/example/schema.json

If your endpoint requires authentication, you can pass query parameters and/or custom HTTP headers:

./gradlew :shared:downloadApolloSchema -Pcom.apollographql.apollo.endpoint=https://your.graphql.endpoint -Pcom.apollographql.apollo.schema=src/main/graphql/com/example/schema.json  "-Pcom.apollographql.apollo.headers=Authorization=Bearer YOUR_TOKEN" "-Pcom.apollographql.apollo.query_params=key1=value1&key2=value2"

The com.apollographql.apollo.headers and com.apollographql.apollo.query_params properties both take a query string where key and values should be URL encoded.

Intellij Plugin

The JS Graphql Intellij Plugin provides auto-completion, error highlighting, and go-to-definition functionality for your graphql files. You can create a .graphqlconfig file in order to use GraphQL scratch files to work with your schema outside product code, e.g. by writing temporary queries to test resolvers.

Releases

Our release history has the release history.

Releases are hosted on jcenter.

Latest development changes are available in Sonatype's snapshots repository:

  repositories {
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
  }

Migrating to 1.3.x

Apollo-Android version 1.3.0 introduces some fixes and improvements that are incompatible with 1.2.x. Updating should be transparent for simple use cases and your project should compile fine. If you're using more advanced features such as custom schema/graphql files location, Kotlin Gradle scripts and/or transformed queries, or if you encounter a build error after updating, read on for details about the changes.

Gradle plugin changes

The plugin has been rewritten in Kotlin to make it more maintainable and have better support for multiple GraphQL endpoints. Below are the main changes. Read plugin-configuration for a reference of the different options.

New plugin ID

The plugin ID has been changed from com.apollographql.android to com.apollographql.apollo to make it clear that the plugin works also for non-Android projects. com.apollographql.android will be removed in a future revision.

// Replace:
apply plugin: 'com.apollographql.android'

// With:
apply plugin: 'com.apollographql.apollo'

Using multiple services

The plugin now requires that you specify multiple services explicitly. If you previously had the following layout:

src/main/graphql/com/github/schema.json
src/main/graphql/com/github/GetRepositories.graphql
src/main/graphql/com/starwars/schema.json
src/main/graphql/com/starwars/GetHeroes.graphql

You will need to define 2 services:

apollo {
  service("github") {
    sourceFolder.set("com/github")
    rootPackageName.set("com.github")
  }
  service("starwars") {
    sourceFolder.set("com/starwars")
    rootPackageName.set("com.starwars")
  }
}

Specifying schema and GraphQL files location

The root schemaFilePath, outputPackageName and sourceSets.graphql are removed and will throw an error if you try to use them. Instead you can use [CompilationUnit] to control what files the compiler will use as inputs.

// Replace:
sourceSets {
  main.graphql.srcDirs += "/path/to/your/graphql/queries/dir"
}

// With:
apollo {
  onCompilationUnit {
     graphqlSourceDirectorySet.srcDirs += "/path/to/your/graphql/queries/dir"
  }
}

// Replace
apollo {
  sourceSet {
    schemaFilePath = "/path/to/your/schema.json"
    exclude = "**/*.gql"
  }
  outputPackageName = "com.example"
}

// With:
apollo {
  onCompilationUnit {
     schemaFile = "/path/to/your/schema.json"
     graphqlSourceDirectorySet.exclude("**/*.gql")
     rootPackageName = "com.example"
  }
}

Kotlin DSL

The plugin uses Gradle Properties to support lazy configuration and wiring tasks together.

If you're using Groovy build.gradle build scripts it should work transparently but Kotlin build.gradle.kts build scripts will require you to use the Property.set API:

apollo {
  // Replace:
  setGenerateKotlinModels(true)

  // With:
  generateKotlinModels.set(true)
}

Also, the classes of the plugin have been split into an api part and an internal one. If you were relying on fully qualified class names from your build.gradle.kts files, you will have to tweak them:

// Replace:
import com.apollographql.apollo.gradle.ApolloExtension

// With:
import com.apollographql.apollo.gradle.api.ApolloExtension

Reverting to the 1.2.x plugin

If, despite the above, you can't make it work, you can keep the 1.2.x plugin. It is available in the apollo-gradle-plugin-deprecated artifact. Make sure to open an issue as the 1.2.x plugin will be removed in a future version.

Breaking changes in generated Kotlin models with inline fragments:

Field inlineFragment is no longer generated with a new Apollo 1.3.0 release for Kotlin models.

For example:

previous version of model with inline fragments

data class Hero(
    val __typename: String,
    /**
     * The name of the character
     */
    val name: String,
    val inlineFragment: HeroCharacter?
  ) {
    val asHuman: AsHuman? = inlineFragment as? AsHuman

    val asDroid: AsDroid? = inlineFragment as? AsDroid
...

new version of generated model with inline fragments

  data class Hero(
    val __typename: String,
    /**
     * The name of the character
     */
    val name: String,
    val asHuman: AsHuman?,
    val asDroid: AsDroid?
  )

Motivation: there is an issue with previous version of generated model, there are cases when specified multiple inline fragments should be resolved for the same GraphQL type. For example imagine that GraphQL schema defines this hierarchy of types Character <- Hero <- Human. Having this GraphQL query:

query {
  character {
    name
    ... on Hero { ... }
    ... on Human { ... }
   }
}

both inline fragments on Hero and on Human should be resolved for character type Human as Hero is super type of Human.

Previous version of generated model for Character didn't resolve both inline fragments but rather first declared ... on Hero. New version resolves both fragments on Hero and on Human.

Migration:

If you have this code to get access to the resolved inline fragment:

when (hero.inlineFragment) {
    is Hero.AsHuman -> ...
    is Hero.AsDroid -> ...
}

you should change it to check all declared inline fragments for nullability, as it's possible now to have multiple resolved fragments:

if (hero.asHuman != null) {
  ...
}

if (hero.asDroid != null) {
  ...
}

Singularization

Singularization rules have been improved (see 1888). That means the name of some classes that were previously wrongly or badly singularized might have changed. Check for a generated class with a similar name if that happens.

Nested class names

Nested classes are now allowed to have the same name as their parent (see 1893). If you were previously using such a class, the numbered suffix will be removed.

Transformed queries removal

Version 1.3.0 can now optionally generate a OperationOutput.json file. This file will contain the generated queries source, operation name and operation ID. You can use them to whitelist the operation on your server or any other use case. See 1841 for details.

Since OperationOutput.json is a superset of the transformed queries, transformed queries have been removed. If you were using transformed queries, you will now have to use OperationOutput.json.

Espresso Idling Resources

Idling Resources integration is moved to AndroidX! This is a potential breaking change for users who has not migrated to AndroidX yet. If you haven't you can still use the 1.2.x version in your test code.

The artifact is also renamed to make its intention more obvious. Documentation for idling resource can be found here

  // Replace:
  androidTestImplementation("com.apollographql.apollo:apollo-espresso-support:x.y.z")

  // With:
  androidTestImplementation("com.apollographql.apollo:apollo-idling-resource:x.y.z")

Advanced topics

Advanced topics are available in the official docs:

License

The MIT License (MIT)

Copyright (c) 2019 Meteor Development Group, Inc.

apollo-android's People

Contributors

sav007 avatar renovate-bot avatar martinbonnin avatar marwanad avatar digitalbuddha avatar felipecsl avatar trevorblades avatar visheshvadhera avatar abernix avatar brianplummer avatar renovate[bot] avatar dsteve595 avatar tasomaniac avatar zacsweers avatar kassim avatar jaredsburrows avatar ghostbuster91 avatar adammc331 avatar martijnwalraven avatar lgawin avatar hwillson avatar imgurpreetsk avatar xrd avatar caerbannog avatar baconz avatar tuncaulubilge avatar tmeasday avatar steventannz avatar ojh102 avatar manijshrestha avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.