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

GraphQLでフロントエンドの複雑性とたたかう

narirou
September 03, 2019

 GraphQLでフロントエンドの複雑性とたたかう

narirou

September 03, 2019
Tweet

More Decks by narirou

Other Decks in Technology

Transcript

  1. Masanari Hamada @narirou ͓࢓ࣄ 2015೥৽ଔೖࣾ GYAO! WEB ͷΞʔΩςΫνϟ࡮৽ GYAO ಈըϓϨʔϠʔ࡮৽

    GYAO iOS SwiftԽ/ϦϑΝΫλϦϯά౳ σβΠϯγεςϜ / JAMStack / WEBඪ४ ʹڵຯ͕͋Γ·͢ ࣥච WEB+DB PRESS ͷϑϩϯτΤϯυ࿈ࡌهࣄͱͯ͠Storybookɺ HeadlessCMSͷهࣄΛࣥච
  2. query(userId: ID!) { history(userId: $userId) { videos { id title

    } } } ྫ͑͹ө૾ͷࢹௌཤྺͷྫ͸ɺGraphQLͰ͋Ε͹ɺҎԼͷΫΤϦͰ໨ తͷσʔλ͕औಘͰ͖Δ
  3. query Heros { heros(first: 10) { name } } {

    "heros": [ { "name": "R2-D2" } ] } export function Users() { const { data } = useQuery(HeroNameQuery); return data.heros.map(hero => <User name={hero.name} />); }
  4. type Post { id: String! title: String! publishedAt: DateTime! likes:

    Int! @default(value: 0) blog: Blog @relation(name: "Posts") } type Blog { id: String! name: String! description: String posts: [Post!]! @relation(name: "Posts") } GraphQL SDL (schema definition language) εΩʔϚઃܭͷهड़ݴޠΛSDLͱͯ͠൚༻తʹࡦఆ ܕͷఆٛͱͯ͠໌ࣔతͰཧղ͠΍͍͢
  5. Interface interface Post { id: ID! title: String! text: String!

    } ❖ ඪ४Ͱ࣋ͭܕ(Scalar Type)ʹ͸ɺString, Int ͳͲ ❖ ! ͸ non-nullable Λද͢
  6. Fragment ❖ ܁Γฦ͕͠ଟ͘ग़ݱ͢ΔͳͲΫΤϦશମ͕ංେԽ͢Δ ❖ ࠶ར༻ՄೳͳΫΤϦͷҰ෦Λ੾Γग़ͯ͠දݱͰ͖Δ { leftComparison: hero(episode: EMPIRE) {

    ...comparisonFields } rightComparison: hero(episode: JEDI) { ...comparisonFields } } fragment comparisonFields on Character { name appearsIn friends { name } }
  7. Apollo Client Λར༻͢Δ import ApolloClient from 'apollo-boost'; import gql from

    'graphql-tag'; const client = new ApolloClient({ uri: 'https://48p1r2roz4.sse.codesandbox.io', }); client .query({ query: gql` { rates(currency: "USD") { currency } } ` }) .then(result => console.log(result));
  8. import React from "react"; import { useQuery } from "@apollo/react-hooks";

    import gql from "graphql-tag"; import Link from "./Link"; const GET_VISIBILITY_FILTER = gql` { visibilityFilter @client } `; function FilterLink({ filter, children }) { const { data, client } = useQuery(GET_VISIBILITY_FILTER); return ( <Link onClick={() => client.writeData({ data: { visibilityFilter: filter } }) active={data.visibilityFilter === filter} > {children} </Link> ) }
  9. { posts { title text labels { name } thumbnail

    { width height url } } } export type BlogPostsQuery = { posts: Maybe< Array< Pick< BlogPost, | "title" | "text" > & { labels: Maybe<Array<Pick< thumbnail: Pick<Image, "u } > >; }; ྫ͑͹ graphql-codegen ͰࠨͷΑ͏ͳΫΤϦΛม׵͢Δͱɺ ӈهͷΑ͏ͳtypes͕ੜ੒͞ΕΔ
  10. const GreetingQuery = gql` query getGreeting($language: String!) { greeting(language: $language)

    { message } } `; function Hello() { const { loading, error, data } = useQuery(GreetingQuery, { variables: { language: 'english' }, }); if (loading) return <p>Loading ...</p>; return <h1>Hello {data.greeting.message}!</h1>; }
  11. export function useGreetingQuery( baseOptions?: ReactApolloHooks.QueryHookOptions< GetGreetingQuery, GetGreetingQueryVariables > ) {

    return ReactApolloHooks.useQuery< GetGreetingQuery, GetGreetingQueryVariables >(StoreTitlesDocument, baseOptions); } export type GetGreetingQueryHookResult = ReturnType<typeof useGetGreetingQuery ΫΤϦ(CustomHook)ͷࣗಈੜ੒ ͞Βʹɺ@apollo/react-hooks ͱͷ࿈ܞ͢ΔͱɺΫΤϦ͔Β ReactHooks༻ͷΧελϜϑοΫΛࣗಈੜ੒͠ɺܕ҆શͳঢ়ଶͰΫΤ ϦΛར༻Ͱ͖Δɻ
  12. query Heros { messages(first: 99999999) { title messages(first: 99999999) {

    title messages(first: 99999999) { title } } } } 1. ύϑΥʔϚϯεΫϦςΟΧϧͳΫΤϦ͕ൃߦ͞ΕΔ ެ։͢ΔGraphQLαʔόʔ͸ɺηΩϡϦςΟΛҙࣝ͢Δඞཁ͕͋Δ ྫ͑͹ɺҎԼͷΑ͏ͳΫΤϦ͸ڐ༰ͨ͘͠ͳ͍…
  13. ❖ αΠζΛ੍ݶ͢Δ ❖ ωετͷ੍ݶ͢Δ graphql-depth-limit ͰωετΛ੍ݶ͢Δ ❖ ෳࡶ౓Λܭࢉ੍͠ݶ͢Δ ❖ ΫΤϦΛϗϫΠτϦετొ࿥͢Δ

    (Persisted Queries) ΫΤϦΛࣄલʹhashԽ͓͖ͯ͠ɺ௨৴࣌΋hash஋Λ༻͍ͯߦ͏ ڐՄ͞ΕͨhashͷΫΤϦͷΈڐ༰ͯ͠ϨεϙϯεΛฦ͢ 1. ύϑΥʔϚϯεΫϦςΟΧϧͳΫΤϦ͕ൃߦ͞ΕΔ खॱ͕ෳࡶͳͨΊɺΑΓΑ͍ղܾࡦ͕΄͍͠ͱ͜Ζ..
  14. ΑΓਂ͘஌Δʹ͸ (ࢀߟจݙ) ❖ GraphQL, ApolloͷެࣜυΩϡϝϯτ ❖ ΫΤϦͷجૅΛ஌Δ: [Queries and Mutations](https://graphql.org/learn/queries/)

    ❖ എܠΛ஌Δ: [Github Blog | The GitHub GraphQL API](https://githubengineering.com/the- github-graphql-api/) ❖ ApolloLinkΛ஌Δ: [Apollo Link Overview](https://www.apollographql.com/docs/link/ overview/) ❖ ϕετϓϥΫςΟεΛ஌Δ: [GraphQL Best Practice](https://graphql.org/learn/best-practices/) ❖ ੍ݶΛ͔͚Δ: [HOW TO SECURE A GRAPHQL API (THE COMPLETE VULNERABILITY CHECKLIST)](https://leapgraph.com/graphql-api-security) ❖ ੍ݶΛ͔͚Δ: [GraphQLͱPsersisted Query by @Quramy](https://qiita.com/Quramy/items/ b3943a0c27f3ade2c57d)