|
1 |
| -import { Application } from "./deps.ts"; |
| 1 | +import { Application, Router } from "./deps.ts"; |
2 | 2 | import { applyGraphQL, gql } from "./deps.ts";
|
| 3 | +import type { InputType, PayloadType } from "./types.ts"; |
3 | 4 |
|
4 | 5 | const app = new Application();
|
5 | 6 |
|
| 7 | +app.use(async (ctx, next) => { |
| 8 | + await next(); |
| 9 | + const rt = ctx.response.headers.get("X-Response-Time"); |
| 10 | + console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`); |
| 11 | +}); |
| 12 | + |
| 13 | +app.use(async (ctx, next) => { |
| 14 | + const start = Date.now(); |
| 15 | + await next(); |
| 16 | + const ms = Date.now() - start; |
| 17 | + ctx.response.headers.set("X-Response-Time", `${ms}ms`); |
| 18 | +}); |
| 19 | + |
6 | 20 | const types = gql`
|
7 |
| - type Dino { |
8 |
| - name: String |
9 |
| - image: String |
| 21 | + type Beer { |
| 22 | + breweryId: ID! |
| 23 | + id: ID! |
| 24 | + name: String! |
| 25 | + type: String! |
10 | 26 | }
|
11 |
| - input DinoInput { |
12 |
| - name: String |
13 |
| - image: String |
| 27 | + input CreateBeerInput { |
| 28 | + clientMutationId: String! |
| 29 | + name: String! |
| 30 | + type: String! |
| 31 | + breweryId: ID! |
14 | 32 | }
|
15 |
| - type ResolveType { |
16 |
| - done: Boolean |
| 33 | + type CreateBeerPayload { |
| 34 | + beer: Beer! |
| 35 | + clientMutationId: String! |
17 | 36 | }
|
18 | 37 | type Query {
|
19 |
| - getDino(name: String): Dino |
20 |
| - getDinos: [Dino!]! |
| 38 | + beer(id: ID!): Beer |
| 39 | + beers: [Beer!]! |
21 | 40 | }
|
22 | 41 | type Mutation {
|
23 |
| - addDino(input: DinoInput!): ResolveType! |
| 42 | + createBeer(input: CreateBeerInput!): CreateBeerPayload! |
24 | 43 | }
|
25 | 44 | `;
|
26 | 45 |
|
27 |
| -const dinos = [ |
| 46 | +type Beer = { id: number; breweryId: number; name: string; type: string }; |
| 47 | + |
| 48 | +const beers: Beer[] = [ |
28 | 49 | {
|
29 |
| - name: "Tyrannosaurus Rex", |
30 |
| - image: "🦖", |
| 50 | + id: 1, |
| 51 | + breweryId: 1, |
| 52 | + name: "Costumes & Karaoke", |
| 53 | + type: "IPA", |
31 | 54 | },
|
32 | 55 | ];
|
33 | 56 |
|
34 | 57 | const resolvers = {
|
35 | 58 | Query: {
|
36 |
| - getDino: (_, { name }) => { |
37 |
| - const dino = dinos.find((dino) => dino.name.includes(name)); |
38 |
| - if (!dino) { |
39 |
| - throw new Error(`No dino name includes ${name}`); |
| 59 | + beer: (_: unknown, { id }: Beer) => { |
| 60 | + const beer = beers.find((beer) => beer.id === id); |
| 61 | + if (!beer) { |
| 62 | + throw new Error( |
| 63 | + `Beer with the id of '${id}' was not able to be found.` |
| 64 | + ); |
40 | 65 | }
|
41 |
| - return dino; |
| 66 | + return beer; |
42 | 67 | },
|
43 |
| - getDinos: () => { |
44 |
| - return dinos; |
| 68 | + beers: () => { |
| 69 | + return beers; |
45 | 70 | },
|
46 | 71 | },
|
47 | 72 | Mutation: {
|
48 |
| - addDino: (_, { input: { name, image } }) => { |
49 |
| - dinos.push({ |
| 73 | + createBeer: ( |
| 74 | + _: unknown, |
| 75 | + { |
| 76 | + input: { clientMutationId, name, type, breweryId }, |
| 77 | + }: InputType<Beer> |
| 78 | + ): PayloadType<{ beer: Beer }> => { |
| 79 | + const id = |
| 80 | + beers.reduce((prev, current) => { |
| 81 | + if (prev > current.id) { |
| 82 | + return prev; |
| 83 | + } |
| 84 | + |
| 85 | + return current.id; |
| 86 | + }, 0) + 1; |
| 87 | + |
| 88 | + const beer: Beer = { |
| 89 | + id, |
| 90 | + breweryId, |
50 | 91 | name,
|
51 |
| - image, |
52 |
| - }); |
| 92 | + type, |
| 93 | + }; |
| 94 | + |
| 95 | + beers.push(beer); |
| 96 | + |
53 | 97 | return {
|
54 |
| - done: true, |
| 98 | + beer, |
| 99 | + clientMutationId, |
55 | 100 | };
|
56 | 101 | },
|
57 | 102 | },
|
58 | 103 | };
|
59 | 104 |
|
60 |
| -const GraphQLService = applyGraphQL({ |
| 105 | +const GraphQLService = await applyGraphQL<Router>({ |
| 106 | + Router, |
61 | 107 | typeDefs: types,
|
62 | 108 | resolvers: resolvers,
|
63 | 109 | });
|
|
0 commit comments