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

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

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

DjangoCongress JP 2019発表資料

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のクエリ(?)をかく クエリ内のパラメータを定義