ntziolis / ionic-apollo-simple-app

Explains how to develop Ionic application with Apollo GraphQL client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ionic Apollo Simple App

Explains how to develop Ionic app with Apollo.

Run app at your local machine

Clone this repository and exec :

cd ionic-apollo-simple-app
npm -g install ionic@latest
npm install // # or yarn
ionic serve

Development Guide

From this point I explain how to integrate GraphQL into Ionic project step by step.

Scaffold Ionic App

You can create the new Ionic app project via

npm install -g ionic@latest
ionic start

GraphQL Server Side

GraphQL is a query language for API developed by Facebook.

This app uses graph.qool as GraphQL server.

This server defines one simple model User, which is extended a graph.cool's built-in model. For example, the following GraphQL query:

{
  allUsers(last: 100) {
    id, name
  }
}

returns data such as:

{
  "data": {
    "allUsers": [
      {
        "id": "cipgms0x44a2k01p1nlnrfr8z",
        "name": "Quramy"
      }
    ]
  }
}

Try query explorer here.

GraphQL Client Dev tools

Before development your app, I introduce two utility libraries for GraphQL client-side development.

  • ts-graphql-plugin displays auto completion and syntax & semantics errors for GraphQL query in your .ts source codes.
    complete
  • apollo-codegen generates TypeScript type annotations from GraphQL query in your source codes.

To install them via exec:

npm install -S graphql-tag
npm install -D apollo-codegen ts-graphql-plugin

And edit tsconfig.json and package.json.

/* tsconfig.json */

 "compilerOptions": {
    // ...
    "plugins": [
      {
        "name": "ts-graphql-plugin",
        "schema": "schema.json",
        "tag": "gql"
      }
    ]
/* tsconfig.json */

  "scripts": {
    // ...
    "gen": "apollo-codegen generate --target ts --output src/__generated__.ts \"src/**/*.ts\""
  },

Finally, download GraphQL Schema JSON file from graph.cool prayground and save it as schema.json under the project. playground_dl;

Ok, it's ready to go! Open src/pages/home/home.ts in your editor or IDE.

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

// Append the following
import gql from 'graphql-tag';

const query = gql`
  fragment UserSummary on User {
    id, name
  }

  query Users {
    allUsers(last: 100) {
      ...UserSummary,
    }
  }
`;

@Component({
// ...

And save hoge.ts then, exec npm run gen script. After successfully running open src/__generated__.ts, you can get the following generated type annotation:

export type UsersQuery = {
  allUsers:  Array< {
    id: string,
    name: string | null,
  } >,
};

export type UserSummaryFragment = {
  id: string,
  name: string | null,
};

The above types allow us to treat GraphQL queries strictly typed.

GarphQL Client Side

You should add a GraphQL client library into your project. This app uses [http://dev.apollodata.com/angular2/] as a GraphQL client.

npm install -S apollo-client apollo-angular

Network Interface

First, set up GraphQL api connection into this app.

Open src/app.module.ts and append the following snippet.

/* app.module.ts */
import { ApolloClient, createNetworkInterface } from 'apollo-client';
import { ApolloModule } from 'apollo-angular';

export const client = new ApolloClient({
  // networkInterface: createNetworkInterface('https://api.graph.cool/simple/v1/cipglmpu146dt01mzwqctkbwd'),
  networkInterface: createNetworkInterface('https://your-graph.cool-endpoint'),
});

export function provideClient(): ApolloClient {
  return client;
}

The provideClient function is called Angular DI as provider of ApolloClient. ApolloModule.forRoot() creates a new Angular module and bind ApolloClient provider.

@NgModule({
  // ...
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    ApolloModule.forRoot(provideClient), // <- Append this line
  ],
  // ...
})

Execute Query

We're ready to execute GraphQL query using ApolloClient provided by Angular DI. Open src/pages/home/home.ts and add a dependent service as an argument of constructor.

import gql from 'graphql-tag';
import { Apollo } from 'apollo-angular';  // Apollo client service
import { UsersQuery, UserSummaryFragment } from '../../__generated__'; // <- Import generated types by `npm run gen`
import { Observable } from 'rxjs/Observable';

const query = gql`
# ...
`;

export class HomePage {
  constructor(
    public navCtrl: NavController,
    private apollo: Apollo, // <- Add apollo client as an Angular service
  ) { }
}

A private member field apollo is used as a GraphQL API client. Use this service like the following:

const query = gql`
  fragment UserSummary on User {
    id, name
  }

  query Users {
    allUsers(last: 100) {
      ...UserSummary,
    }
  }
`;

export class HomePage {
  users$: Observable<UserSummaryFragment[]>;

  constructor(
    public navCtrl: NavController,
    private apollo: Apollo,
  ) {
    this.users$ = this.apollo.query<UsersQuery>({ query })
      .map(({ data }) => data.allUsers);
  }
}

The Users GraphQL query is executed by this.apollo.query<UsersQuery>({ query }). As described above, this query results a JSON data such as:

{
  "data": {
    "allUsers": [
      { "id": "u001", "name": "Alice" },
      { "id": "u002", "name": "Bob" }
    ]
  }
}

And apollo-codegen tells us that the type of the result of this query is UsersQuery. Apollo service returns result as a RxJS Observable object. So using rxjs operators (e.g. map or pluck or etc...), we can convert the apollo result to Observable<UserSummrayFragment[]>.

Display Query Result

Using async pipe in your template, Anguar automatically subscribe(and also unsubscribe) the apollo stream.

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
  <ion-list>
    <button ion-item *ngFor="let user of users$ | async">
      {{user.name}}
    </button>
  </ion-list>
</ion-content>

Run your app

That's all, start app via ionic serve!

home

About

Explains how to develop Ionic application with Apollo GraphQL client


Languages

Language:TypeScript 45.4%Language:CSS 27.3%Language:HTML 20.4%Language:JavaScript 6.8%