使用AWS AppSync和Apollo开始使用GraphQL

这篇文章是 Angular Advent Calendar 2018 第二十二天的文章。

简而言之

    • AWS AppSyncを使って画面にデータを表示してみたい方

 

    • フロントエンドエンジニアでも簡単にGraphQLを触ってみたい方

 

    GraphQLを導入するか迷っている方向けの記事

我很痛苦使用REST

aws.png

我们使用Angular + AWS来运营一个服务,如上图所示,用于显示从REST API返回的信息。然而,随着服务需求增加,需要在屏幕上获取的信息也变得更多。

    • 複数のAPIを呼び出さないと欲しい情報が取れない

 

    • レスポンス内の一部のデータしか利用しないのに、余分なデータも返される

 

    APIのリクエスト数やRTTの増加

最近有很多令人困扰的事情发生了…

为什么选择GraphQL?

那么我们该如何解决这个问题呢?

    • 欲しい情報だけ返す新しいAPIを増やす

 

    既存のAPIにfieldsパラメータなどを実装する

我认为有很多种方法可以做到这一点。

在使用GraphQL时,根据模式设置的不同

    • 複数のサービスからシンプルに無駄なく欲しい情報を取得できる

 

    リポジトリに対してクエリを生やすことでデータの取得が可能になるため、既存のプロジェクトに影響を与えず小さく導入できそう

因为觉得在这一点上非常有吸引力,
所以这次我使用了AWS AppSync作为GraphQL服务,
并使用Angular + Apollo来实现数据,
我想要分享这些信息。

想要快速入门GraphQL,使用AWS和Angular的步骤是什么?

大致的流程 or 简要的流程

    1. 参考此指南创建AWS AppSync(省略了建设步骤)。

 

    1. 安装Apollo + AWS AppSync JavaScript SDK。

 

    使用Angular实现。
appsync.png

完成的代码 de

这次的完整代码可以在这里找到:
https://github.com/hiroyuki-nishi/apollo-angular

这次使用的服务的说明

appsync (1).png

AWS AppSync 是由 AWS 提供的全托管的无服务器 GraphQL 服务。它与其他 AWS 资源的集成容易,可以将 DynamoDB 作为数据源,并自动生成 GraphQL 模式,还能在 AppSync 控制台上查看结果。

apollo-logo.png

Apollo是由Meteor Development Group开发的可以在后端和前端使用GraphQL的库。

我打算使用Apollo在客户端实现GraphQL,它可以与Angular、React、Vue、Meteor、Ember、Polymer等框架兼容。

首先安装!

一旦成功创建了AWS AppSync,我们将开始进行Angular的实施。
首先,创建一个新的项目,并添加Apollo和AWS AppSyncSDK。

$ ng new apollo-in-angular
$ ng add apollo-angular
$ npm install --save aws-appsync

为了在Angular 6.x及更高版本中使AWS AppSyncSDK正常运行,需要在polyfills.ts文件中添加以下内容。

// polyfills.ts
(window as any).global = window;

从Angular中获取数据

接下来,我们将创建一个从AWS AppSync获取数据的服务。
在这里,我们主要进行AWS AppSync端点的配置。

//graphql.service.ts
import AWSAppSyncClient from 'aws-appsync';
import { AUTH_TYPE } from 'aws-appsync/lib';
import { Apollo } from 'apollo-angular';
import { Injectable } from '@angular/core';


@Injectable()
export class GraphqlService {
  constructor(private apollo: Apollo) {}

  hydrated() {
    const appsyncClient = new AWSAppSyncClient({
      disableOffline: true,
      url: '<Your AppSync Api Url>',
      region: '<Your AppSync Api Region>',
      auth: {
        type: AUTH_TYPE.API_KEY,
        apiKey: '<Your AppSync ApiKey>',
      },
    });
    this.apollo.setClient(appsyncClient);
    return appsyncClient.hydrated();
  }
}

在参考Apollo文档的情况下,接下来我们将定义Query服务。这次的实现是假设从多个仓库获取信息的查询。

//query.service.ts
import {Injectable} from '@angular/core';
import {Query} from 'apollo-angular';
import gql from 'graphql-tag';

export interface Application {
  id: string;
  itunesstore_id: string;
  updated: string;
}

export interface Profile {
  identifier: string;
}

export interface ApplicationsWithProfiles {
  listApplications: {
    items: Application[];
  };
  listProfiles: {
    items: Profile[];
  };
}


@Injectable({
  providedIn: 'root',
})
export class ApplicationsGQL extends Query<ApplicationsWithProfiles> {
  document = gql`
    query {
      listApplications {
        items {
          id
          itunesstore_id
          updated
        }
      }
    listProfiles {
        items {
          identifier
        }
      }
    }
  `;
}

创建一个用于显示最后一个组件的组件。

// app.component.ts
import { Component, OnInit } from '@angular/core';
import { map } from 'rxjs/operators';
import { Application, QueryGQL, Profile } from './query.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'GraphQL with Apollo';
  applications: Application[];
  profiles: Profile[];

  constructor(private service: QueryGQL) {}

  ngOnInit(): void {
    this.service.watch().valueChanges.pipe(
      map(v => v.data)
    ).subscribe(res => {
      this.applications = res.listApplications.items;
      this.profiles = res.listProfiles.items;
    });
  }
}

这是最终完成的界面。
通过一个请求成功地从多个代码库中获取到了所需的信息。太厉害了。

スクリーンショット 2018-12-21 23.07.51.png

总结

在实际使用AWS AppSync时,我认为可能会遇到AWS的限制以及只有实际使用才能了解的情况。然而,能够在一个查询中组合多个数据源,达到获取所需的信息,这一点非常吸引人。同时,能够轻松地对AWS资源进行操作也是非常好的。

今年剩下的時間不多了,不过现在尝试一下GraphQL又如何呢!

第23天是@studioTeaTwo先生。请多多关照。

广告
将在 10 秒后关闭
bannerAds