| # Prepation | |||||
| ``` | |||||
| npm init | |||||
| ``` | |||||
| See More <https://graphql-code-generator.com/docs/getting-started/installation> | |||||
| ``` | |||||
| npm add --save graphql | |||||
| ``` | |||||
| or | |||||
| ``` | |||||
| yarn add graphql | |||||
| ``` | |||||
| ``` | |||||
| npm add --save-dev @graphql-codegen/cli | |||||
| ``` | |||||
| or | |||||
| ``` | |||||
| yarn add -D @graphql-codegen/cli | |||||
| ``` | |||||
| ``` | |||||
| npx graphql-codegen init | |||||
| ``` | |||||
| ``` | |||||
| npm add --save-dev @graphql-codegen/typescript | |||||
| ``` | |||||
| or | |||||
| ``` | |||||
| yarn add -D @graphql-codegen/typescript | |||||
| ``` | |||||
| # Server | # Server | ||||
| ``` | |||||
| npm add apollo-server | |||||
| ``` | |||||
| - start creating types in schema.ts | |||||
| ``` | |||||
| npm install @types/node --save-dev | |||||
| ```typescript | |||||
| import gql from "graphql-tag"; | |||||
| export const pizzaSchema = gql``; | |||||
| ``` | ``` | ||||
| ``` | |||||
| npx tsc --init --rootDir src --outDir build \ | |||||
| --esModuleInterop --resolveJsonModule --lib es6 \ | |||||
| --module commonjs --allowJs true --noImplicitAny true | |||||
| ``` | |||||
| - create types and querys | |||||
| - show generated code | |||||
| - create index.ts | |||||
| - index.ts | |||||
| ```typescript | |||||
| import { ApolloServer } from "apollo-server/dist"; | |||||
| const server = new ApolloServer({}); | |||||
| server.listen().then(({ url, subscriptionsUrl }) => { | |||||
| console.log(`🚀 Server ready at ${url}`) | |||||
| console.log(`🚀 Subscriptions ready at ${subscriptionsUrl}`); | |||||
| }); | |||||
| ``` | ``` | ||||
| npm install --save-dev ts-node nodemon rimraf uuid @types/uuid apollo-link-ws | |||||
| ``` | |||||
| - show playground and run listPizza | |||||
| - create resolve config with empty array | |||||
| - create pizza list | |||||
| - create pizzaResolver.ts | |||||
| - add read/list function | |||||
| - add resolver to resolver config | |||||
| - show get and list | |||||
| - add toppings | |||||
| - add list | |||||
| - add resolver | |||||
| - add toppings to pizza mocks | |||||
| - show type resolvers | |||||
| - show Mutation | |||||
| - show Subscription | |||||
| - show finished api | |||||
| # UI | # UI | ||||
| * init new Angular project | |||||
| - init new Angular project | |||||
| ``` | ``` | ||||
| ng new frontend | |||||
| git clone git@ziermach.de:cziermann/angular-demo-template.git | |||||
| ``` | ``` | ||||
| ``` | ``` | ||||
| npm i | npm i | ||||
| ``` | ``` | ||||
| * init codegen | |||||
| - init codegen | |||||
| ``` | ``` | ||||
| npx graphql-codegen init | npx graphql-codegen init | ||||
| npm i | npm i | ||||
| ``` | ``` | ||||
| * check angular | |||||
| * use url "http://localhost:400" | |||||
| * fragment path default | |||||
| * plugin default | |||||
| * output default | |||||
| * set uri in graphql module | |||||
| * move | |||||
| * graphql.module | |||||
| - check angular | |||||
| - use url "http://localhost:400" | |||||
| - fragment path default | |||||
| - plugin default | |||||
| - output default | |||||
| - set uri in graphql module | |||||
| - move | |||||
| - graphql.module | |||||
| ## Pizza component | ## Pizza component | ||||
| ng g c pizza-list | ng g c pizza-list | ||||
| ``` | ``` | ||||
| * copy | |||||
| * app.module.ts | |||||
| * app.component.ts | |||||
| * styles.css | |||||
| - copy | |||||
| - app.module.ts | |||||
| - app.component.ts | |||||
| - styles.css |
| import { ApolloServer, PubSub } from "apollo-server/dist"; | |||||
| import { ApolloServer } from "apollo-server/dist"; | |||||
| import { Resolvers, ChangePizzaDto, ChangeToppingDto } from "./generated/graphql"; | import { Resolvers, ChangePizzaDto, ChangeToppingDto } from "./generated/graphql"; | ||||
| import { pizzaSchema } from "./schema/pizza"; | |||||
| import { pizzaSchema } from "./schema/schema"; | |||||
| import { PizzaResolver } from "./resolver/pizza-resolver"; | import { PizzaResolver } from "./resolver/pizza-resolver"; | ||||
| import { ToppingResolver } from "./resolver/topping-resolver"; | import { ToppingResolver } from "./resolver/topping-resolver"; | ||||
| const server = new ApolloServer({ | const server = new ApolloServer({ | ||||
| typeDefs: pizzaSchema, | typeDefs: pizzaSchema, | ||||
| resolvers: resolvers as any, | resolvers: resolvers as any, | ||||
| } | |||||
| ); | |||||
| }); | |||||
| server.listen().then(({ url, subscriptionsUrl }) => { | server.listen().then(({ url, subscriptionsUrl }) => { | ||||
| console.log(`🚀 Server ready at ${url}`) | console.log(`🚀 Server ready at ${url}`) |
| listTopping: [Topping]! | listTopping: [Topping]! | ||||
| } | } | ||||
| interface MutationResponse { | |||||
| code: String! | |||||
| success: Boolean! | |||||
| message: String! | |||||
| } | |||||
| input ChangePizzaDto { | input ChangePizzaDto { | ||||
| name: String! | name: String! | ||||
| toppingIds: [ID]! | toppingIds: [ID]! |
| </section> | </section> | ||||
| <section> | <section> | ||||
| <section> | <section> | ||||
| <h1>Demo</h1> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Basics</h2> | |||||
| <h1>Basics</h1> | |||||
| </section> | </section> | ||||
| <section> | <section> | ||||
| <ul> | <ul> | ||||
| <li> | <li> | ||||
| Mutations | Mutations | ||||
| </li> | </li> | ||||
| <li> | |||||
| Subscriptions | |||||
| </li> | |||||
| <li> | <li> | ||||
| Variables | Variables | ||||
| </li> | </li> | ||||
| </section> | </section> | ||||
| <section> | <section> | ||||
| <h3>Mutation</h3> | <h3>Mutation</h3> | ||||
| <pre><code data-trim data-noescape> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| mutation { | mutation { | ||||
| createPizza (createPizzaDto: { | createPizza (createPizzaDto: { | ||||
| name: "My Awesome Pizza" | name: "My Awesome Pizza" | ||||
| </code> | </code> | ||||
| </pre> | </pre> | ||||
| </section> | </section> | ||||
| <section> | |||||
| <h2>Subscriptions</h2> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Define Subscription</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| type Subscription { | |||||
| pizzasChanged: [Pizza]! | |||||
| toppingsChanged: [Topping]! | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Subscription</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| subscription PizzaChanged { | |||||
| pizzasChanged { | |||||
| id | |||||
| name | |||||
| } | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| </section> | </section> | ||||
| <section> | <section> | ||||
| <section> | |||||
| <h1>Live Demo</h1> | |||||
| </section> | |||||
| <section> | <section> | ||||
| <img | <img | ||||
| src="/assets/apollo-logo.png" | src="/assets/apollo-logo.png" | ||||
| <p>graphql-codegen</p> | <p>graphql-codegen</p> | ||||
| <p>apollo-angular</p> | <p>apollo-angular</p> | ||||
| </section> | </section> | ||||
| <section> | |||||
| <h2> | |||||
| Requirements | |||||
| </h2> | |||||
| <ul> | |||||
| <li>npm</li> | |||||
| <li>nodejs</li> | |||||
| <li>tsc</li> | |||||
| <li>npx</li> | |||||
| <li>git</li> | |||||
| </ul> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Setup Server</h2> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Init nodejs</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| $ mkdir server && cd server | |||||
| $ npm init | |||||
| # entry point: build/index.js | |||||
| $ npx tsc --init --rootDir src --outDir build \ | |||||
| --esModuleInterop --resolveJsonModule --lib es6 \ | |||||
| --module commonjs --allowJs true --noImplicitAny true | |||||
| $ npm i --save-dev uuid @types/uuid nodemon ts-node typescript | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Create nodemon</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| $ touch nodemon.json | |||||
| </code> | |||||
| <code data-trim data-noescape> | |||||
| { | |||||
| "watch": ["src"], | |||||
| "ext": ".ts,.js", | |||||
| "ignore": [], | |||||
| "exec": "ts-node ./src/index.ts" | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>add script commands to package.json</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| "scripts": { | |||||
| "prebuild": "npm run generate", | |||||
| "prestart": "npm run generate", | |||||
| "generate": "graphql-codegen --config codegen.yml", | |||||
| "start": "nodemon", | |||||
| "build": "rimraf ./build && tsc" | |||||
| } | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Init graphql</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| $ npm add --save-dev graphql | |||||
| $ npm add --save-dev @graphql-codegen/cli | |||||
| $ npm add --save-dev @graphql-codegen/typescript | |||||
| $ npm add apollo-server | |||||
| $ npm i --save-dev apollo-link-ws | |||||
| $ npx graphql-codegen init | |||||
| # (x) Backend | |||||
| # schema: ./src/schema/*.ts | |||||
| # plugins: | |||||
| ◉ TypeScript (required by other typescript plugins) | |||||
| ◉ TypeScript Resolvers (strongly typed resolve functions) | |||||
| # output: skip | |||||
| # introspection: n | |||||
| # config: skip | |||||
| # script: generate | |||||
| $ npm i | |||||
| $ mkdir src && touch src/index.ts | |||||
| </code> | |||||
| </pre> | |||||
| </section> | |||||
| <section> | |||||
| <h2>Setup Frontend</h2> | |||||
| </section> | |||||
| <section> | |||||
| <h3>Init Project</h3> | |||||
| <pre> | |||||
| <code data-trim data-noescape> | |||||
| $ git clone git@ziermach.de:cziermann/angular-demo-template.git | |||||
| $ git checkout graphql-template | |||||
| or | |||||
| $ cd angular-demo-template | |||||
| $ npm add apollo-angular | |||||
| $ ng add apollo-angular | |||||
| $ npm add graphql | |||||
| $ npm add --save-dev @graphql-codegen/cli | |||||
| $ npm i | |||||
| $ npx graphql-codegen init | |||||
| # with Angular | |||||
| # skip all | |||||
| # script: generate | |||||
| $ npm i | |||||
| </code> | |||||
| move the graphql.module.ts in src/ | |||||
| </pre> | |||||
| </section> | |||||
| </section> | </section> | ||||
| </div> | </div> | ||||
| </div> | </div> |