| ``` | ``` | ||||
| ``` | ``` | ||||
| npm install --save-dev ts-node nodemon rimraf | |||||
| npm install --save-dev ts-node nodemon rimraf uuid @types/uuid | |||||
| ``` | ``` | ||||
| "queryType": { | "queryType": { | ||||
| "name": "Query" | "name": "Query" | ||||
| }, | }, | ||||
| "mutationType": null, | |||||
| "mutationType": { | |||||
| "name": "Mutation" | |||||
| }, | |||||
| "subscriptionType": null, | "subscriptionType": null, | ||||
| "types": [ | "types": [ | ||||
| { | { | ||||
| "enumValues": null, | "enumValues": null, | ||||
| "possibleTypes": null | "possibleTypes": null | ||||
| }, | }, | ||||
| { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangePizzaDto", | |||||
| "description": null, | |||||
| "fields": null, | |||||
| "inputFields": [ | |||||
| { | |||||
| "name": "name", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "SCALAR", | |||||
| "name": "String", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| }, | |||||
| { | |||||
| "name": "toppingIds", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "LIST", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "SCALAR", | |||||
| "name": "ID", | |||||
| "ofType": null | |||||
| } | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "interfaces": null, | |||||
| "enumValues": null, | |||||
| "possibleTypes": null | |||||
| }, | |||||
| { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangeToppingDto", | |||||
| "description": null, | |||||
| "fields": null, | |||||
| "inputFields": [ | |||||
| { | |||||
| "name": "name", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "SCALAR", | |||||
| "name": "String", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "interfaces": null, | |||||
| "enumValues": null, | |||||
| "possibleTypes": null | |||||
| }, | |||||
| { | |||||
| "kind": "OBJECT", | |||||
| "name": "Mutation", | |||||
| "description": null, | |||||
| "fields": [ | |||||
| { | |||||
| "name": "createPizza", | |||||
| "description": null, | |||||
| "args": [ | |||||
| { | |||||
| "name": "createPizzaDto", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangePizzaDto", | |||||
| "ofType": null | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "OBJECT", | |||||
| "name": "Pizza", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "isDeprecated": false, | |||||
| "deprecationReason": null | |||||
| }, | |||||
| { | |||||
| "name": "updatePizza", | |||||
| "description": null, | |||||
| "args": [ | |||||
| { | |||||
| "name": "pizzaId", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "SCALAR", | |||||
| "name": "ID", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| }, | |||||
| { | |||||
| "name": "updatedPizzaDto", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangePizzaDto", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "OBJECT", | |||||
| "name": "Pizza", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "isDeprecated": false, | |||||
| "deprecationReason": null | |||||
| }, | |||||
| { | |||||
| "name": "createTopping", | |||||
| "description": null, | |||||
| "args": [ | |||||
| { | |||||
| "name": "createToppingDto", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangeToppingDto", | |||||
| "ofType": null | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "OBJECT", | |||||
| "name": "Topping", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "isDeprecated": false, | |||||
| "deprecationReason": null | |||||
| }, | |||||
| { | |||||
| "name": "updateTopping", | |||||
| "description": null, | |||||
| "args": [ | |||||
| { | |||||
| "name": "toppingId", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "SCALAR", | |||||
| "name": "ID", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| }, | |||||
| { | |||||
| "name": "updatedToppingDto", | |||||
| "description": null, | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "INPUT_OBJECT", | |||||
| "name": "ChangeToppingDto", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "defaultValue": null | |||||
| } | |||||
| ], | |||||
| "type": { | |||||
| "kind": "NON_NULL", | |||||
| "name": null, | |||||
| "ofType": { | |||||
| "kind": "OBJECT", | |||||
| "name": "Topping", | |||||
| "ofType": null | |||||
| } | |||||
| }, | |||||
| "isDeprecated": false, | |||||
| "deprecationReason": null | |||||
| } | |||||
| ], | |||||
| "inputFields": null, | |||||
| "interfaces": [], | |||||
| "enumValues": null, | |||||
| "possibleTypes": null | |||||
| }, | |||||
| { | { | ||||
| "kind": "OBJECT", | "kind": "OBJECT", | ||||
| "name": "__Schema", | "name": "__Schema", |
| "@types/mime": "*" | "@types/mime": "*" | ||||
| } | } | ||||
| }, | }, | ||||
| "@types/uuid": { | |||||
| "version": "8.0.0", | |||||
| "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz", | |||||
| "integrity": "sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==" | |||||
| }, | |||||
| "@types/websocket": { | "@types/websocket": { | ||||
| "version": "1.0.0", | "version": "1.0.0", | ||||
| "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.0.tgz", | "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.0.tgz", | ||||
| "deprecated-decorator": "^0.1.6", | "deprecated-decorator": "^0.1.6", | ||||
| "iterall": "^1.1.3", | "iterall": "^1.1.3", | ||||
| "uuid": "^3.1.0" | "uuid": "^3.1.0" | ||||
| }, | |||||
| "dependencies": { | |||||
| "uuid": { | |||||
| "version": "3.4.0", | |||||
| "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", | |||||
| "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" | |||||
| } | |||||
| } | } | ||||
| }, | }, | ||||
| "graphql-upload": { | "graphql-upload": { | ||||
| "tough-cookie": "~2.5.0", | "tough-cookie": "~2.5.0", | ||||
| "tunnel-agent": "^0.6.0", | "tunnel-agent": "^0.6.0", | ||||
| "uuid": "^3.3.2" | "uuid": "^3.3.2" | ||||
| }, | |||||
| "dependencies": { | |||||
| "uuid": { | |||||
| "version": "3.4.0", | |||||
| "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", | |||||
| "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", | |||||
| "dev": true | |||||
| } | |||||
| } | } | ||||
| }, | }, | ||||
| "require-directory": { | "require-directory": { | ||||
| "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" | ||||
| }, | }, | ||||
| "uuid": { | "uuid": { | ||||
| "version": "3.4.0", | |||||
| "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", | |||||
| "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" | |||||
| "version": "8.2.0", | |||||
| "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", | |||||
| "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" | |||||
| }, | }, | ||||
| "valid-url": { | "valid-url": { | ||||
| "version": "1.0.9", | "version": "1.0.9", |
| "description": "", | "description": "", | ||||
| "main": "build/index.js", | "main": "build/index.js", | ||||
| "dependencies": { | "dependencies": { | ||||
| "@types/uuid": "^8.0.0", | |||||
| "apollo-server": "^2.15.1", | "apollo-server": "^2.15.1", | ||||
| "graphql": "^15.3.0", | "graphql": "^15.3.0", | ||||
| "typescript": "^3.9.6" | |||||
| "typescript": "^3.9.6", | |||||
| "uuid": "^8.2.0" | |||||
| }, | }, | ||||
| "devDependencies": { | "devDependencies": { | ||||
| "@graphql-codegen/cli": "1.16.3", | "@graphql-codegen/cli": "1.16.3", |
| import { Pizza } from "../generated/graphql"; | import { Pizza } from "../generated/graphql"; | ||||
| import { ToppingList } from "./topping-list"; | |||||
| import { ToppingResolver } from "../resolver/topping-resolver"; | import { ToppingResolver } from "../resolver/topping-resolver"; | ||||
| export const PizzaList: Pizza[] = [ | export const PizzaList: Pizza[] = [ | ||||
| name: "420", | name: "420", | ||||
| toppings: [ | toppings: [ | ||||
| ToppingResolver.getByName("Pineapple"), | ToppingResolver.getByName("Pineapple"), | ||||
| ToppingResolver.getByName("Fish_sticks"), | |||||
| ] | ] | ||||
| } | } | ||||
| ] | ] |
| }, | }, | ||||
| { | { | ||||
| id: "5", | id: "5", | ||||
| name: "fish sticks", | |||||
| name: "Fish_sticks", | |||||
| } | } | ||||
| toppingName: Scalars['ID']; | toppingName: Scalars['ID']; | ||||
| }; | }; | ||||
| export type ChangePizzaDto = { | |||||
| name: Scalars['String']; | |||||
| toppingIds: Array<Maybe<Scalars['ID']>>; | |||||
| }; | |||||
| export type ChangeToppingDto = { | |||||
| name: Scalars['String']; | |||||
| }; | |||||
| export type Mutation = { | |||||
| __typename?: 'Mutation'; | |||||
| createPizza: Pizza; | |||||
| updatePizza: Pizza; | |||||
| createTopping: Topping; | |||||
| updateTopping: Topping; | |||||
| }; | |||||
| export type MutationCreatePizzaArgs = { | |||||
| createPizzaDto?: Maybe<ChangePizzaDto>; | |||||
| }; | |||||
| export type MutationUpdatePizzaArgs = { | |||||
| pizzaId: Scalars['ID']; | |||||
| updatedPizzaDto: ChangePizzaDto; | |||||
| }; | |||||
| export type MutationCreateToppingArgs = { | |||||
| createToppingDto?: Maybe<ChangeToppingDto>; | |||||
| }; | |||||
| export type MutationUpdateToppingArgs = { | |||||
| toppingId: Scalars['ID']; | |||||
| updatedToppingDto: ChangeToppingDto; | |||||
| }; | |||||
| export type ResolverTypeWrapper<T> = Promise<T> | T; | export type ResolverTypeWrapper<T> = Promise<T> | T; | ||||
| Topping: ResolverTypeWrapper<Topping>; | Topping: ResolverTypeWrapper<Topping>; | ||||
| Query: ResolverTypeWrapper<{}>; | Query: ResolverTypeWrapper<{}>; | ||||
| Boolean: ResolverTypeWrapper<Scalars['Boolean']>; | Boolean: ResolverTypeWrapper<Scalars['Boolean']>; | ||||
| ChangePizzaDto: ChangePizzaDto; | |||||
| ChangeToppingDto: ChangeToppingDto; | |||||
| Mutation: ResolverTypeWrapper<{}>; | |||||
| }; | }; | ||||
| /** Mapping between all available schema types and the resolvers parents */ | /** Mapping between all available schema types and the resolvers parents */ | ||||
| Topping: Topping; | Topping: Topping; | ||||
| Query: {}; | Query: {}; | ||||
| Boolean: Scalars['Boolean']; | Boolean: Scalars['Boolean']; | ||||
| ChangePizzaDto: ChangePizzaDto; | |||||
| ChangeToppingDto: ChangeToppingDto; | |||||
| Mutation: {}; | |||||
| }; | }; | ||||
| export type PizzaResolvers<ContextType = any, ParentType extends ResolversParentTypes['Pizza'] = ResolversParentTypes['Pizza']> = { | export type PizzaResolvers<ContextType = any, ParentType extends ResolversParentTypes['Pizza'] = ResolversParentTypes['Pizza']> = { | ||||
| listTopping?: Resolver<Array<Maybe<ResolversTypes['Topping']>>, ParentType, ContextType>; | listTopping?: Resolver<Array<Maybe<ResolversTypes['Topping']>>, ParentType, ContextType>; | ||||
| }; | }; | ||||
| export type MutationResolvers<ContextType = any, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> = { | |||||
| createPizza?: Resolver<ResolversTypes['Pizza'], ParentType, ContextType, RequireFields<MutationCreatePizzaArgs, never>>; | |||||
| updatePizza?: Resolver<ResolversTypes['Pizza'], ParentType, ContextType, RequireFields<MutationUpdatePizzaArgs, 'pizzaId' | 'updatedPizzaDto'>>; | |||||
| createTopping?: Resolver<ResolversTypes['Topping'], ParentType, ContextType, RequireFields<MutationCreateToppingArgs, never>>; | |||||
| updateTopping?: Resolver<ResolversTypes['Topping'], ParentType, ContextType, RequireFields<MutationUpdateToppingArgs, 'toppingId' | 'updatedToppingDto'>>; | |||||
| }; | |||||
| export type Resolvers<ContextType = any> = { | export type Resolvers<ContextType = any> = { | ||||
| Pizza?: PizzaResolvers<ContextType>; | Pizza?: PizzaResolvers<ContextType>; | ||||
| Topping?: ToppingResolvers<ContextType>; | Topping?: ToppingResolvers<ContextType>; | ||||
| Query?: QueryResolvers<ContextType>; | Query?: QueryResolvers<ContextType>; | ||||
| Mutation?: MutationResolvers<ContextType>; | |||||
| }; | }; | ||||
| import { ApolloServer } from "apollo-server/dist"; | import { ApolloServer } from "apollo-server/dist"; | ||||
| import { Resolvers } from "./generated/graphql"; | |||||
| import { Resolvers, ChangePizzaDto, ChangeToppingDto } from "./generated/graphql"; | |||||
| import { pizzaSchema } from "./schema/pizza"; | import { pizzaSchema } from "./schema/pizza"; | ||||
| import { PizzaResolver } from "./resolver/pizza-resolver"; | import { PizzaResolver } from "./resolver/pizza-resolver"; | ||||
| import { ToppingResolver } from "./resolver/topping-resolver"; | import { ToppingResolver } from "./resolver/topping-resolver"; | ||||
| listTopping: (root, args, context) => { | listTopping: (root, args, context) => { | ||||
| return ToppingResolver.list(); | return ToppingResolver.list(); | ||||
| }, | }, | ||||
| }, | |||||
| Mutation: { | |||||
| createPizza: (root, args, context) => { | |||||
| return PizzaResolver.create(args.createPizzaDto as ChangePizzaDto); | |||||
| }, | |||||
| updatePizza: (root, args, context) => { | |||||
| return PizzaResolver.update(args.pizzaId, args.updatedPizzaDto as ChangePizzaDto); | |||||
| }, | |||||
| createTopping: (root, args, context) => { | |||||
| return ToppingResolver.create(args.createToppingDto as ChangeToppingDto); | |||||
| }, | |||||
| updateTopping: (root, args, context) => { | |||||
| return ToppingResolver.update(args.toppingId, args.updatedToppingDto as ChangeToppingDto); | |||||
| }, | |||||
| } | } | ||||
| } | } | ||||
| import { Topping, Pizza, } from "../generated/graphql"; | |||||
| import { Topping, Pizza, ChangePizzaDto, Maybe } from "../generated/graphql"; | |||||
| import { PizzaList } from "../data/pizza-list"; | import { PizzaList } from "../data/pizza-list"; | ||||
| import { v4 as uuidv4 } from 'uuid'; | |||||
| import { ToppingResolver } from "./topping-resolver"; | |||||
| export class PizzaResolver { | export class PizzaResolver { | ||||
| static getById = (id: string): Pizza => { | static getById = (id: string): Pizza => { | ||||
| return PizzaList.filter(pizza => pizza.name === name)[0]; | return PizzaList.filter(pizza => pizza.name === name)[0]; | ||||
| }; | }; | ||||
| static create = (pizzaCreateDto: ChangePizzaDto): Pizza => { | |||||
| const toppings: Topping[] = pizzaCreateDto.toppingIds | |||||
| .map<string>((toppingId) => toppingId as string) | |||||
| .map<Topping>((toppingId) => ToppingResolver.getById(toppingId)); | |||||
| const pizza: Pizza = { | |||||
| id: uuidv4(), | |||||
| name: pizzaCreateDto.name, | |||||
| toppings: toppings | |||||
| } | |||||
| console.log(`Create Pizza ...`, pizza) | |||||
| return pizza; | |||||
| }; | |||||
| static update = (pizzaId: string, pizzaUpdateDto: ChangePizzaDto): Pizza => { | |||||
| const pizza = PizzaResolver.getById(pizzaId); | |||||
| if (!pizza) { | |||||
| throw new Error( | |||||
| `No Pizza found with id ${pizzaId}` | |||||
| ) | |||||
| } | |||||
| const toppings: Topping[] = pizzaUpdateDto.toppingIds | |||||
| .map<string>((toppingId: Maybe<string>) => toppingId as string) | |||||
| .map<Topping>((toppingId: string) => ToppingResolver.getById(toppingId)); | |||||
| pizza.name = pizzaUpdateDto.name; | |||||
| pizza.toppings = toppings; | |||||
| console.log(`Update Pizza ...`, pizza) | |||||
| return pizza; | |||||
| }; | |||||
| } | } |
| import { Topping, } from "../generated/graphql"; | |||||
| import { Topping, ChangeToppingDto, } from "../generated/graphql"; | |||||
| import { ToppingList } from "../data/topping-list"; | import { ToppingList } from "../data/topping-list"; | ||||
| import { v4 as uuidv4 } from 'uuid'; | |||||
| import { EEXIST } from "constants"; | |||||
| export class ToppingResolver { | export class ToppingResolver { | ||||
| static getById = (id: string): Topping => { | static getById = (id: string): Topping => { | ||||
| return ToppingList.filter(topping => topping.id === id)[0]; | return ToppingList.filter(topping => topping.id === id)[0]; | ||||
| return ToppingList; | return ToppingList; | ||||
| }; | }; | ||||
| static create = (toppingCreateDto: ChangeToppingDto): Topping => { | |||||
| const topping: Topping = { | |||||
| id: uuidv4(), | |||||
| name: toppingCreateDto.name, | |||||
| } | |||||
| console.log(`Create Topping ...`, topping) | |||||
| return topping; | |||||
| }; | |||||
| static update = (toppingId: string, toppingUpdateDto: ChangeToppingDto): Topping => { | |||||
| const topping = ToppingResolver.getById(toppingId); | |||||
| if (!topping) { | |||||
| throw new Error( | |||||
| `No Topping found with id ${toppingId}` | |||||
| ) | |||||
| } | |||||
| topping.name = toppingUpdateDto.name; | |||||
| console.log(`Update Topping ...`, topping) | |||||
| return topping; | |||||
| }; | |||||
| } | } |
| listPizza: [Pizza]! | listPizza: [Pizza]! | ||||
| listTopping: [Topping]! | listTopping: [Topping]! | ||||
| } | } | ||||
| `; | |||||
| interface MutationResponse { | |||||
| code: String! | |||||
| success: Boolean! | |||||
| message: String! | |||||
| } | |||||
| input ChangePizzaDto { | |||||
| name: String! | |||||
| toppingIds: [ID]! | |||||
| } | |||||
| input ChangeToppingDto { | |||||
| name: String! | |||||
| } | |||||
| type Mutation { | |||||
| createPizza(createPizzaDto: ChangePizzaDto): Pizza! | |||||
| updatePizza(pizzaId: ID!, updatedPizzaDto: ChangePizzaDto!): Pizza! | |||||
| createTopping(createToppingDto: ChangeToppingDto): Topping! | |||||
| updateTopping(toppingId: ID!, updatedToppingDto: ChangeToppingDto!): Topping! | |||||
| } | |||||
| `; |
| .reveal .justify-start { justify-content: flex-start; } | .reveal .justify-start { justify-content: flex-start; } | ||||
| .reveal .justify-center { justify-content: center; } | .reveal .justify-center { justify-content: center; } | ||||
| .reveal .justify-end { justify-content: flex-end; } | .reveal .justify-end { justify-content: flex-end; } | ||||
| .scrollable-slide { | |||||
| height: 800px; | |||||
| overflow-y: auto !important; | |||||
| } |
| <section> | <section> | ||||
| <h2>Pizza service</h2> | <h2>Pizza service</h2> | ||||
| </section> | </section> | ||||
| <section class="scrollable-slide"> | |||||
| <img | |||||
| src="/assets/restful-architecture.png" | |||||
| alt="rest-architecture" | |||||
| style="background: transparent;" | |||||
| class="demo-logo" | |||||
| /> | |||||
| </section> | |||||
| <section class="scrollable-slide"> | |||||
| <img | |||||
| src="/assets/graphql-architecture.png" | |||||
| alt="graphql-architecture" | |||||
| style="background: transparent;" | |||||
| class="demo-logo" | |||||
| /> | |||||
| </section> | |||||
| <section> | <section> | ||||
| <h3>Rest Service</h3> | <h3>Rest Service</h3> | ||||
| <img | <img | ||||
| class="demo-logo" | class="demo-logo" | ||||
| /> | /> | ||||
| </section> | </section> | ||||
| </section> | |||||
| <section> | |||||
| </section> | |||||
| </section> | |||||
| <section> | |||||
| <section> | |||||
| <h1>benefits</h1> | |||||
| </section> | |||||
| <section> | |||||
| <h2>No more Over- and Underfetching</h2> | |||||
| fixed data structures provide to much or not enough data | |||||
| </section> | |||||
| <section> | |||||
| <h2>Type/Schema System</h2> | |||||
| <ul> | |||||
| <li>Graphql uses an strict Type and Schema</li> | |||||
| <li>The Client can be sure about what it get</li> | |||||
| <li>aswell as the server</li> | |||||
| </ul> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Growing Community and Integrations</h2> | |||||
| <ul> | |||||
| <li> | |||||
| Good Client side Integrations Angular/React/VueJs and more. | |||||
| </li> | |||||
| <li>Server side Integrations in Typescript/Java and more.</li> | |||||
| <li>Well working code-generator for client and server</li> | |||||
| <li>Alot of well writen Documentation</li> | |||||
| </ul> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Self Documenting</h2> | |||||
| <img | |||||
| src="/assets/self-doku.png" | |||||
| alt="self-doku example" | |||||
| style="background: transparent;" | |||||
| class="demo-logo" | |||||
| /> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Faster API Development</h2> | |||||
| </section> | |||||
| <section class="scrollable-slide"> | |||||
| <h2>pros/cons</h2> | |||||
| <a | |||||
| style="font-size: 14px;" | |||||
| href="https://www.altexsoft.com/blog/engineering/graphql-core-features-architecture-pros-and-cons/" | |||||
| > | |||||
| <img | |||||
| src="/assets/pros-cons.png" | |||||
| alt="pros-cons" | |||||
| style="background: transparent;" | |||||
| class="demo-logo" | |||||
| /> | |||||
| </a> | |||||
| </section> | |||||
| </section> | |||||
| <section> | |||||
| <section> | |||||
| <h1>disadvantages</h1> | |||||
| </section> | |||||
| <section> | |||||
| <h3>more complex</h3> | |||||
| </section> | |||||
| <section> | |||||
| <h3>no file uploading</h3> | |||||
| </section> | |||||
| </section> | |||||
| <section> | |||||
| <section> | |||||
| <h1>Demo</h1> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Basics</h2> | |||||
| </section> | |||||
| <section> | |||||
| <ul> | |||||
| <li> | |||||
| Types | |||||
| </li> | |||||
| <li> | |||||
| Querys | |||||
| </li> | |||||
| <li> | |||||
| Mutations | |||||
| </li> | |||||
| <li> | |||||
| Variables | |||||
| </li> | |||||
| </ul> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Types</h2> | |||||
| </section> | |||||
| <section> | |||||
| <pre><code data-trim data-noescape> | |||||
| type Pizza { | |||||
| id: ID! | |||||
| name: String! | |||||
| toppings: [Topping!]! | |||||
| } | |||||
| type Topping { | |||||
| id: ID! | |||||
| name: String! | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Querys</h2> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Define Querys</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| type Query { | |||||
| getPizzaById(pizzaId: ID!): Pizza! | |||||
| getToppingById(toppingId: ID!): Topping! | |||||
| getPizzaByName(pizzaName: ID!): Pizza! | |||||
| getToppingByName(toppingName: ID!): Topping! | |||||
| listPizza: [Pizza]! | |||||
| listTopping: [Topping]! | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Simple Query</h3> | |||||
| <pre><code data-trim data-noescape> | |||||
| { | |||||
| listPizza { | |||||
| id | |||||
| name | |||||
| } | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>More Complex Query</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| { | |||||
| getPizzaById(pizzaId: "0") { | |||||
| id | |||||
| name | |||||
| toppings { | |||||
| name | |||||
| } | |||||
| } | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Mutations</h2> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Define Mutations</h3> | |||||
| <pre><code data-trim data-noescape> | |||||
| type Mutation { | |||||
| createPizza(createPizzaDto: ChangePizzaDto): Pizza! | |||||
| updatePizza(pizzaId: ID!, updatedPizzaDto: ChangePizzaDto!): Pizza! | |||||
| createTopping(createToppingDto: ChangeToppingDto): Topping! | |||||
| updateTopping(toppingId: ID!, updatedToppingDto: ChangeToppingDto!): Topping! | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Mutation</h3> | |||||
| <pre><code data-trim data-noescape> | |||||
| mutation { | |||||
| createPizza (createPizzaDto: { | |||||
| name: "My Awesome Pizza" | |||||
| toppingIds: "1" | |||||
| }) { | |||||
| id | |||||
| name | |||||
| toppings { | |||||
| id | |||||
| name | |||||
| } | |||||
| } | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <img | |||||
| src="/assets/apollo-logo.png" | |||||
| alt="apollo logo" | |||||
| style="background: transparent;" | |||||
| class="demo-logo" | |||||
| /> | |||||
| <p>graphql-codegen</p> | |||||
| <p>apollo-angular</p> | |||||
| </section> | |||||
| </section> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||