2018/10/16

Graphql


more easier than RESTAPIClient側のRequestを柔軟に対応できる感じで
 QueryLanguage!条件は自分で指定し、結果を返す
 QueryLanguageをサポートするServicesTypeFieldFunctions

What kinds of objects might they return? What fields are available on those sub-objects? That's where the schema comes in.

A GraphQL service is created by defining types and fields on those types,then providing functions for each field on each type.

Once a GraphQL service is running (typically at a URL on a web service), 
 it can be sent GraphQL queries to validate and execute. 
 A received query is first checked to ensure it only refers to the types and fields defined, then runs the provided functions to produce a result.

Learn more about GraphQL—the query language, type system, how the GraphQL service works, 

Like many type systems, GraphQL supports interfaces

the query has exactly the same shape as the result. This is essential to GraphQL, because you always get back what you expect, and the server knows exactly what fields the client is asking for.==>後で統計、分析できるね!

GraphQL queries can traverse related objects and their fields, 
 letting clients fetch lots of related data in one request, 
 instead of making several roundtrips as one would need in a classic REST architecture.

GraphQL, every field and nested object can get its own set of arguments, making GraphQL a complete replacement for making multiple API fetches. 
↓↓heightFOOT単位で返す
{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}

have reusable units called fragments. Fragments let you construct sets of fields, and then include them in queries where you need to.
=>重複する部分をFragmentとして定義し、使うところでIncludeする感じ
    …some Fragement


・「query HeroNameAndFriends
  query->operation type
      HeroNameAndFriends—>operation name


 GraphQL has a first-class way to factor dynamic values out of the query, and pass them as a separate dictionary. These values are called variables.
    can have default value
    @include—>directive 
     @skip(if: Boolean)—>directive 
 query HeroNameAndFriends($episode: Episode = XXX,$withFriends) {
    hero(episode: $episode) {
            name
            friend @include(if: $withFriends)
   }
    }


mutationー>POST it (更新) then  GET 更新結果
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

While query fields are executed in parallel, mutation fields run in series, one after the other.


inline Fragment
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
#__typename, a meta field, when you dont know the type, you can use it 
# when ep is Droid
    ... on Droid {
      primaryFunction
    }
# when ep is Human
    ... on Human {
      height
    }
  }
}


query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}

query(request) Sample

{
  human(id: "1000") {
    name
    height
  }
   # Queries can have comments!
    friends {
      name
    }
}

DataResponse
{
  "data": {
    "hero": {
      "name": "R2-D2",
     height: 170.2
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}