LoginSignup
2
1

More than 1 year has passed since last update.

NestJSで、Stripe APIを呼び出すGraphQL APIを作る方法

Posted at

この記事は、GraphQL Advent Calendar 2022 17日目の記事です。

Stripeのデータ取得は、基本的にREST APIを通して行います。

しかし、複数のデータソース(商品と料金など)を横断したいケースや、必要なデータのみ取得するクエリを書きたい場合など、GraphQL APIでの実装が向いているパターンも存在します。

今回の記事では、NestJSを利用して、Stripeのデータを取得するGraphQL APIを作る方法を紹介します。

プロジェクトのセットアップ

NestJSでプロジェクトを作成する場合は、NestJS CLIを利用します。

$ npm i -g @nestjs/cli
$ nest new project-name

Stripe SDKを利用する準備

続いて、Stripe SDKをNestJSから呼び出す準備をしましょう。

$ npm install nestjs-stripe @nestjs/config

// 環境変数でStripeのシークレット/制限付きAPIキーを設定
$ echo "STRIPE_SECRET_API_KEY=rk_test_xxx" > .env.local 

設定内容の詳細については、以下の記事をご一読ください。

GraphQL

最後にGraphQL APIを実装するためのライブラリをインストールします。

$ npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express

app.module.tsに設定を追加する

インストールしたモジュールなどを利用できるようにしましょう。

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';
import { StripeModule } from 'nestjs-stripe';
import { ConfigModule, ConfigService } from '@nestjs/config';


@Module({
  imports: [
    // 環境変数の読み込み
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: ['.env.local']
    }),

    // Stripe SDKの読み込み
    StripeModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        apiKey: configService.get('STRIPE_SECRET_API_KEY'),
        apiVersion: '2022-08-01'
      })
    }),

    // GraphQLの読み込み
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      debug: false,
      playground: true,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      sortSchema: true
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

GraphQL APIを実装する

準備ができましたので、実装を開始します。

GraphQLのデータモデルを作成しよう

GraphQLのスキーマやNestJSでの実装のベースになるデータモデルを作成しましょう。

$ nest generate class model
CREATE src/model/model.spec.ts (143 bytes)
CREATE src/model/model.ts (22 bytes)

src/model/model.tsに、Product(商品)とPrice(料金)の型を簡単に定義します。

import { Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Price {
    @Field(type => ID)
    id: string;

    @Field({nullable: true})
    nickname?: string;

    @Field()
    currency: string;
    
    @Field()
    unit_amount: number
}

@ObjectType()
export class Product {
    @Field(type => ID)
    id: string;

    @Field({ nullable: true })
    name: string;

    @Field({ nullable: true })
    description?: string;

    @Field(() => [Price], { nullable: true})
    prices?: Price[]
}

Stripe APIを呼び出すServiceを作成する

Stripe SDKを呼び出す処理は、Serviceとして分離しておきましょう。

$ nest generate service stripe-api
CREATE src/stripe-api/stripe-api.service.spec.ts (482 bytes)
CREATE src/stripe-api/stripe-api.service.ts (93 bytes)
UPDATE src/app.module.ts (254 bytes)

商品一覧の取得処理と、商品のIDから料金を取得する処理を追加しました。

import { Injectable } from '@nestjs/common';
import { InjectStripe } from 'nestjs-stripe';
import Stripe from 'stripe';

@Injectable()
export class StripeApiService {
    constructor(
        @InjectStripe() private readonly stripe: Stripe
    ) {}

    public async listProducts() {
        return this.stripe.products.list()
    }
    public async findPricesByProductId(productId: string) {
        return this.stripe.prices.list({
            product: productId
        })
    }
}

Resolverを作成しよう

GraphQLのAPIリクエストは、Resolverを通して処理されます。

NestJSのCLIで、Resolverを作成しましょう。

$ nest generate resolver stripe-api
CREATE src/stripe-api/stripe-api.resolver.spec.ts (492 bytes)
CREATE src/stripe-api/stripe-api.resolver.ts (91 bytes)
UPDATE src/app.module.ts (254 bytes)

Resolverから、先ほど作成したServiceを呼び出して処理を実装しましょう。

import { Resolver, Query, ResolveField, Parent } from '@nestjs/graphql';
import { Product } from './model/model';
import { StripeApiService } from './stripe-api.service';

@Resolver(of => Product)
export class StripeApiResolver {
    constructor(
        private readonly stripeAPIService: StripeApiService
    ) {}

    @Query(() => [Product])
    async findProducts() {
        const { data:products } = await this.stripeAPIService.listProducts()
        return products
    }

    @ResolveField()
    async prices(@Parent() product) {
        const { id } = product
        const { data:prices } = await  this.stripeAPIService.findPricesByProductId(id)
        return prices
    }
}

ResolveFieldを利用して、findProductsクエリーから料金データの取得を行なっています。

GraphQL Playgroundで動作を確認する

NestJSで作成したAPIは、REST API同様にnpm start:devでローカル環境で立ち上げることができます。

また、GraphQLの場合、http://localhost:3000/graphqlへアクセスすると、Playgroundが表示されます。

スクリーンショット 2022-11-08 19.31.26.png

Playgroundを利用して、意図したデータが取得できているかなどを確認しましょう。

終わりに

今回の記事では、Stripe APIを呼び出すGraphQL APIの実装方法を紹介しました。

実際のユースケースでは、AWSやGCPなどにホストされた別のデータベース情報なども含めたデータの取得を行う可能性もあります。

NestJSとGraphQLの機能を使いこなして、柔軟なAPI開発を進めましょう。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1