Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DjangoではじめるGraphQLとフロントエンド開発の協業

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 DjangoではじめるGraphQLとフロントエンド開発の協業

DjangoCongress JP 2019発表資料

Avatar for Masaya Nasu

Masaya Nasu

May 18, 2019
Tweet

More Decks by Masaya Nasu

Other Decks in Technology

Transcript

  1. Githubが2017年にAPI v4に採用 > Why GitHub is using GraphQL > GitHub

    chose GraphQL for our API v4 because it offers significantly more flexibility for our integrators. The ability to define precisely the data you want—and only the data you want—is a powerful advantage over the REST API v3 endpoints. GraphQL lets you replace multiple REST requests with a single call to fetch the data you specify. > GitHubは、API v4にGraphQLを選択しました。インテグレータにとって、柔軟性が大 幅に向上するためです。必要なデータ(および必要なデータのみ)を正確に定義できるこ とは、REST API v3エンドポイントを超える強力な利点です。 GraphQLでは、指定した データを取得するために、複数のREST要求を単一の呼び出しに置き換えることができ ます。 https://developer.github.com/v4/
  2. type Ship { id: ID! name: String! shipType: ShipType! }

    type Organization { id: ID! name:String! ships: [Ship] } type Query { ships(name: String, shipType: ShipType): [Ship!]! organizations(name: String): [Organization!]! } APIを定義するスキーマ 型の定義 クエリの定義
  3. データを取得するためのQuery クエリの実行 { "data": { "ships": [ { "name": "aoba",

    "shipType": "HEAVY_CRUISER" } ] } } query ships { ships { name shipType } }
  4. データを更新するためのMutation Mutationの実行 mutation newShip { createShip(input:{name:"aoba", shipType: HEAVY_CRUISER}) { id

    name shipType } } { "data": { "createShip": { "id": "乱数", "name": "aoba", "shipType": "HEAVY_CRUISER" } } }
  5. サンプル from django.db import models from graphene_django import DjangoObjectType import

    graphene class UserModel(models.Model): name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class User(DjangoObjectType): class Meta: model = UserModel class Query(graphene.ObjectType): users = graphene.List(User) def resolve_users(self, info): return UserModel.objects.all() schema = graphene.Schema(query=Query) https://github.com/graphql-python/graphene-django/#examples
  6. GraphQLのスキーマを作成する # 型の作成 class TermType(DjangoObjectType): class Meta: model = Terms

    id = graphene.ID() title = graphene.String() questions = graphene.List(QuestionsType)
  7. リゾルバの作成 class Query(graphene.ObjectType): term = graphene.Field(TermType, id=graphene.ID()) terms = graphene.List(TermType)

    def resolve_term(self, info, id): return Terms.objects.get(pk=id) def resolve_terms(self, info): return Terms.objects.all() 各フィールドに対応する 関数を定義する djangoのormを使用して書ける
  8. Mutationの作成 class CreateTerm(graphene.Mutation): term = graphene.Field(TermType) question = graphene.Field(QuestionsType) answer

    = graphene.Field(AnswersType) class Arguments: title = graphene.String(required=True) questions = graphene.List(QuestionsInputType) クラス名がMutationの名前になる
  9. Mutationの作成 def mutate(self, info, title, questions): term = Terms.objects.create(title=title) for

    question in questions: question_obj = Questions.objects.create( terms=term, description=question.description ) # 略 return CreateTerm(term=term) Argumentフィールドに定義した変数が 引数として渡される
  10. vue-apolloを使ったクエリの実行方法 export default Vue({ name: 'Index', apollo: { terms: gql`query{

    terms { id, title } }` } }) graphql-tagが提供しているテ ンプレートリテラルのタグ クエリをパースしている。 this.termsでアクセス出来る ようになる
  11. methods: { async register() { const result = await this.$apollo.mutate({

    // Query mutation: gql`mutation ($title: String!, $questions: [QuestionsInputType]){ createTerm(title: $title, questions: $questions) { term { title } } }`, // Parameters variables: { title: this.title, questions: this.questions }, }) } } Mutationの実行方法 mutationのクエリ(?)をかく クエリ内のパラメータを定義