Slide 1

Slide 1 text

(SBQI2-#FUUFS&SSPST (SBQI2-0TBLB

Slide 2

Slide 2 text

w (SBQI2-ͷΤϥʔͷϨεϙϯεͷϑΥʔϚοτ͸ܾ·ͬ ͍ͯ·͢ɻ w ͦͷ(SBQI2-ͷΤϥʔͷ࢓༷΍Τϥʔ͕ൃੜͨ͠ͱ͖ ͷϋϯυϦϯάΛ"QPMMP(SBQI2-΍(SBQI2-3VCZ ͳͲͷ࣮૷ྫͰ঺հ͠·͢ɻ

Slide 3

Slide 3 text

(SBQI2-4QFD IUUQTHSBQIRMHJUIVCJPHSBQIRMTQFD

Slide 4

Slide 4 text

Prerelease Working Draft Sat, Oct 5, 2019 Latest Release June 2018 Sun, Jun 10, 2018 Release Notes October 2016 Mon, Oct 31, 2016 Release Notes April 2016 Thu, Apr 7, 2016 Release Notes October 2015 Thu, Oct 1, 2015 Release Notes July 2015 Thu, Jul 2, 2015 Release Notes GraphQL

Slide 5

Slide 5 text

3FTQPOTF'PSNBU { "data": { ... }, "errors": [ ... ] }

Slide 6

Slide 6 text

3FTQPOTF&SSPST Example No 189 { "errors": [ { "message": "Name for character with ID 1002 could not be fetched.", "locations": [ { "line": 6, "column": 7 } ], "path": [ "hero", "heroFriends", 1, "name" ], "extensions": { "code": "CAN_NOT_FETCH_BY_ID", "timestamp": "Fri Feb 9 14:33:09 UTC 2018" } } ] }

Slide 7

Slide 7 text

"QPMMP4FSWFS IUUQTXXXBQPMMPHSBQIRMDPNEPDTBQPMMPTFSWFSEBUB

Slide 8

Slide 8 text

&SSPS)BOEMJOH IUUQTXXXBQPMMPHSBQIRMDPNEPDTBQPMMPTFSWFSEBUBFSSPST "QPMMP4FSWFSQSPWJEFTBDPMMFDUJPOPG QSFEFpOFEFSSPST JODMVEJOH "VUIFOUJDBUJPO&SSPS 'PSCJEEFO&SSPS 6TFS*OQVU&SSPS BOEBHFOFSJD "QPMMP&SSPS

Slide 9

Slide 9 text

"VUIFOUJDBUJPO&SSPS const { ApolloServer, gql, AuthenticationError } = require("apollo-server"); const typeDefs = gql` type Query { authenticationError: String } `; const resolvers = { Query: { authenticationError: (parent, args, context) => { throw new AuthenticationError("must authenticate"); } } };

Slide 10

Slide 10 text

\ FSSPST< \ NFTTBHFNVTUBVUIFOUJDBUF MPDBUJPOT< \ MJOF DPMVNO ^ > QBUI< BVUIFOUJDBUJPO&SSPS > FYUFOTJPOT\ DPEF6/"65)&/5*$"5&% ^ ^ > EBUB\ BVUIFOUJDBUJPO&SSPSOVMM ^ ^

Slide 11

Slide 11 text

"QPMMP$MJFOU IUUQTXXXBQPMMPHSBQIRMDPNEPDTSFBDU

Slide 12

Slide 12 text

&SSPS)BOEMJOH IUUQTXXXBQPMMPHSBQIRMDPNEPDTSFBDUEBUBFSSPSIBOEMJOH • graphQLErrors: An array of errors from the GraphQL endpoint

Slide 13

Slide 13 text

HSBQI2-&SSPST import { ApolloProvider, useQuery } from “@apollo/react-hooks"; function Element() { const { loading, error, data } = useQuery(gql` { authenticationError } `); if (loading) return

Loading...

; if (error) { return error.graphQLErrors.map(({ message, extensions }, i) => (
{message}: {extensions.code}
)) } }

Slide 14

Slide 14 text

NVTUBVUIFOUJDBUF6/"65)&/5*$"5&%

Slide 15

Slide 15 text

(SBQI2-3VCZ IUUQTHSBQIRMSVCZPSHFSSPSTPWFSWJFX

Slide 16

Slide 16 text

&SSPS)BOEMJOH IUUQTHSBQIRMSVCZPSHFSSPSTFSSPS@IBOEMJOH w 4FQU /FX'FBUVSFT w VTF(SBQI2-&YFDVUJPO&SSPSTQSPWJEFTFSSPS IBOEMJOHGPSUIFOFXJOUFSQSFUFS

Slide 17

Slide 17 text

(SBQI2-&YFDVUJPO&SSPS class MySchema < GraphQL::Schema use GraphQL::Execution::Interpreter use GraphQL::Analysis::AST use GraphQL::Execution::Errors rescue_from(ActiveRecord::RecordNotFound) do |err, obj, args, ctx, field| GraphQL::ExecutionError.new( err.message, extensions: {code: ‘RecordNotFound'} ) end end

Slide 18

Slide 18 text

{ "data": null, "errors": [ { "message": "Couldn't find User", "locations": [ { "line": 2, "column": 3 } ], "path": [ "user" ], "extensions": { "code": "RecordNotFound" } } ] }

Slide 19

Slide 19 text

$VTUPN4DBMBST IUUQTHSBQIRMSVCZPSHUZQF@EFpOJUJPOTTDBMBST w "VH /FXGFBUVSFT w "EEFYUFOTJPOTJO$PFSDJPO&SSPS

Slide 20

Slide 20 text

(SBQI2-$PFSDJPO&SSPS module Types class EmailAddress < Types::BaseScalar def self.coerce_input(value, _context) unless URI::MailTo::EMAIL_REGEXP.match(value) raise GraphQL::CoercionError.new( "#{value} is not a valid email address", extensions: { code: “Invalid_Email" } ) end value end end end

Slide 21

Slide 21 text

{ "errors": [ { "message": "example.com is not a valid email address", "locations": [ { "line": 2, "column": 3 } ], "path": [ "query", "user", "email" ], "extensions": { "code": "Invalid_Email", "typeName": "CoercionError" } } ] }

Slide 22

Slide 22 text

(SBQI2-0TBLB