GraphQL 客户端如何使用

首先

    • GraphQLの勉強のため、以下のサイトのfull-stack tutorialをやってみた。

 

    • https://www.apollographql.com/docs/tutorial/introduction/

 

    • サーバー側はなんとか理解したが、クライアント側がReactベースで全く分からない。

 

    代わりにPythonからGraphQL Clientを使用してみた。

GraphQL服务器启动。

cd fullstack-tutorial\final\server
npm run start
http://127.0.0.1:4000/

模式定义

    • LaunchConnection.cursorは、打ち上げデータに付与されているlaunch_date_unixに対応。

 

    • Mission.missionPatchは、打ち上げに対応するアイコン画像情報。大と小があり、デフォルトは大。

 

    User.tokenは、ここではemailをbase64エンコーディングしたもの。
type Query {
  launches(
    """
    The number of results to show. Must be >= 1. Default = 20
    """
    pageSize: Int
    """
    If you add a cursor here, it will only return results _after_ this cursor
    """
    after: String
  ): LaunchConnection!
  launch(id: ID!): Launch
  me: User
}

type Mutation {
  # if false, signup failed -- check errors
  bookTrips(launchIds: [ID]!): TripUpdateResponse!

  # if false, cancellation failed -- check errors
  cancelTrip(launchId: ID!): TripUpdateResponse!

  login(email: String): User
}

type TripUpdateResponse {
  success: Boolean!
  message: String
  launches: [Launch]
}

"""
Simple wrapper around our list of launches that contains a cursor to the
last item in the list. Pass this cursor to the launches query to fetch results
after these.
"""
type LaunchConnection {
  cursor: String!
  hasMore: Boolean!
  launches: [Launch]!
}

type Launch {
  id: ID!
  site: String
  mission: Mission
  rocket: Rocket
  isBooked: Boolean!
}

type Rocket {
  id: ID!
  name: String
  type: String
}

type User {
  id: ID!
  email: String!
  profileImage: String
  trips: [Launch]!
  token: String
}

type Mission {
  name: String
  missionPatch(size: PatchSize): String
}

enum PatchSize {
  SMALL
  LARGE
}

使用Python调用GraphQL Client。

    • 以下のライブラリを使用。

 

    • https://github.com/graphql-python/gql

 

    pip install –pre gql[all]
import json

from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport

transport = AIOHTTPTransport(url="http://127.0.0.1:4000/")
client = Client(transport=transport)

# 打ち上げ予定の一覧を取得 (名前をlaunchesからpageに変更)
query = gql("""
    query GetLaunches {
      page: launches(pageSize: 3) {
        cursor
        hasMore
        launches {
          id
          mission {
            name
            missionPatch(size: SMALL)
          }
        }
      }
    }
""")

result = client.execute(query)
print(json.dumps(result, indent=2))
{
  "page": {
    "cursor": "1605486420",
    "hasMore": true,
    "launches": [
      {
        "id": "109",
        "mission": {
          "name": "Starlink-15 (v1.0)",
          "missionPatch": "https://images2.imgbox.com/9a/96/nLppz9HW_o.png"
        }
      },
      {
        "id": "108",
        "mission": {
          "name": "Sentinel-6 Michael Freilich",
          "missionPatch": null
        }
      },
      {
        "id": "107",
        "mission": {
          "name": "Crew-1",
          "missionPatch": "https://i.imgur.com/BzaSAnx.png"
        }
      }
    ]
  }
}
# ログインしてトークンを取得
query = gql("""
    mutation LoginUser {
      login(email: "daisy@apollographql.com") {
        token
      }
    }
""")

result = client.execute(query)
print(json.dumps(result, indent=2))
{
  "login": {
    "token": "ZGFpc3lAYXBvbGxvZ3JhcGhxbC5jb20="
  }
}
# ヘッダーを設定したclientを作成
headers = {'authorization': 'ZGFpc3lAYXBvbGxvZ3JhcGhxbC5jb20='}
transport = AIOHTTPTransport(url="http://127.0.0.1:4000/", headers=headers)
client = Client(transport=transport)

# 打ち上げの予約
query = gql("""
    mutation BookTrips {
      bookTrips(launchIds: [67, 68, 69]) {
        success
        message
        launches {
          id
        }
      }
    }
""")

result = client.execute(query)
print(json.dumps(result, indent=2))
{
  "bookTrips": {
    "success": true,
    "message": "trips booked successfully",
    "launches": [
      {
        "id": "67"
      },
      {
        "id": "68"
      },
      {
        "id": "69"
      }
    ]
  }
}
# 打ち上げのキャンセル
query = gql("""
    mutation BookTrips {
      cancelTrip(launchId: 68) {
        success
        message
        launches {
          id
        }
      }
    }
""")

result = client.execute(query)
print(json.dumps(result, indent=2))
{
  "cancelTrip": {
    "success": true,
    "message": "trip cancelled",
    "launches": [
      {
        "id": "68"
      }
    ]
  }
}
# ユーザーの情報と予約している打ち上げを取得
query = gql("""
    query {
      me {
        email
        trips {
          id
          mission {
            name
            missionPatch
          }
        }
      }
    }
""")

result = client.execute(query)
print(json.dumps(result, indent=2))
{
  "me": {
    "email": "daisy@apollographql.com",
    "trips": [
      {
        "id": "67",
        "mission": {
          "name": "Merah Putih",
          "missionPatch": "https://images2.imgbox.com/a8/f5/ZgdsrbqW_o.png"
        }
      },
        "id": "69",
        "mission": {
          "name": "SAOCOM 1A",
          "missionPatch": "https://images2.imgbox.com/66/d2/oVB1ofaZ_o.png"
        }
      }
    ]
  }
}

其他

    • SQLite3では、INTEGER型のカラムに対してPRIMARY KEY制約を設定すると、自動インクリメントとなる。

 

    • Sequelize ORMを使用すると、テーブルのカラムにcreatedAtとupdatedAtが追加される。

 

    データベースの更新処理は非同期で実行される。
广告
将在 10 秒后关闭
bannerAds