|
| 1 | +const { ApolloServer, gql } = require("apollo-server"); |
| 2 | + |
| 3 | +let authors = [ |
| 4 | + { |
| 5 | + name: "Robert Martin", |
| 6 | + id: "afa51ab0-344d-11e9-a414-719c6709cf3e", |
| 7 | + born: 1952, |
| 8 | + }, |
| 9 | + { |
| 10 | + name: "Martin Fowler", |
| 11 | + id: "afa5b6f0-344d-11e9-a414-719c6709cf3e", |
| 12 | + born: 1963, |
| 13 | + }, |
| 14 | + { |
| 15 | + name: "Fyodor Dostoevsky", |
| 16 | + id: "afa5b6f1-344d-11e9-a414-719c6709cf3e", |
| 17 | + born: 1821, |
| 18 | + }, |
| 19 | + { |
| 20 | + name: "Joshua Kerievsky", // birthyear not known |
| 21 | + id: "afa5b6f2-344d-11e9-a414-719c6709cf3e", |
| 22 | + }, |
| 23 | + { |
| 24 | + name: "Sandi Metz", // birthyear not known |
| 25 | + id: "afa5b6f3-344d-11e9-a414-719c6709cf3e", |
| 26 | + }, |
| 27 | +]; |
| 28 | + |
| 29 | +/* |
| 30 | + * Suomi: |
| 31 | + * Saattaisi olla järkevämpää assosioida kirja ja sen tekijä tallettamalla kirjan yhteyteen tekijän nimen sijaan tekijän id |
| 32 | + * Yksinkertaisuuden vuoksi tallennamme kuitenkin kirjan yhteyteen tekijän nimen |
| 33 | + * |
| 34 | + * English: |
| 35 | + * It might make more sense to associate a book with its author by storing the author's id in the context of the book instead of the author's name |
| 36 | + * However, for simplicity, we will store the author's name in connection with the book |
| 37 | + */ |
| 38 | + |
| 39 | +let books = [ |
| 40 | + { |
| 41 | + title: "Clean Code", |
| 42 | + published: 2008, |
| 43 | + author: "Robert Martin", |
| 44 | + id: "afa5b6f4-344d-11e9-a414-719c6709cf3e", |
| 45 | + genres: ["refactoring"], |
| 46 | + }, |
| 47 | + { |
| 48 | + title: "Agile software development", |
| 49 | + published: 2002, |
| 50 | + author: "Robert Martin", |
| 51 | + id: "afa5b6f5-344d-11e9-a414-719c6709cf3e", |
| 52 | + genres: ["agile", "patterns", "design"], |
| 53 | + }, |
| 54 | + { |
| 55 | + title: "Refactoring, edition 2", |
| 56 | + published: 2018, |
| 57 | + author: "Martin Fowler", |
| 58 | + id: "afa5de00-344d-11e9-a414-719c6709cf3e", |
| 59 | + genres: ["refactoring"], |
| 60 | + }, |
| 61 | + { |
| 62 | + title: "Refactoring to patterns", |
| 63 | + published: 2008, |
| 64 | + author: "Joshua Kerievsky", |
| 65 | + id: "afa5de01-344d-11e9-a414-719c6709cf3e", |
| 66 | + genres: ["refactoring", "patterns"], |
| 67 | + }, |
| 68 | + { |
| 69 | + title: "Practical Object-Oriented Design, An Agile Primer Using Ruby", |
| 70 | + published: 2012, |
| 71 | + author: "Sandi Metz", |
| 72 | + id: "afa5de02-344d-11e9-a414-719c6709cf3e", |
| 73 | + genres: ["refactoring", "design"], |
| 74 | + }, |
| 75 | + { |
| 76 | + title: "Crime and punishment", |
| 77 | + published: 1866, |
| 78 | + author: "Fyodor Dostoevsky", |
| 79 | + id: "afa5de03-344d-11e9-a414-719c6709cf3e", |
| 80 | + genres: ["classic", "crime"], |
| 81 | + }, |
| 82 | + { |
| 83 | + title: "The Demon ", |
| 84 | + published: 1872, |
| 85 | + author: "Fyodor Dostoevsky", |
| 86 | + id: "afa5de04-344d-11e9-a414-719c6709cf3e", |
| 87 | + genres: ["classic", "revolution"], |
| 88 | + }, |
| 89 | +]; |
| 90 | + |
| 91 | +const typeDefs = gql` |
| 92 | + type Query { |
| 93 | + bookCount: Int! |
| 94 | + authorCount: Int! |
| 95 | + allBooks(name: String, genre: String): [Book!]! |
| 96 | + allAuthors: [Author!]! |
| 97 | + addBook(input: addBookInput): Book |
| 98 | + } |
| 99 | +
|
| 100 | + type Book { |
| 101 | + id: ID! |
| 102 | + title: String! |
| 103 | + author: String! |
| 104 | + published: Int! |
| 105 | + genres: [String!]! |
| 106 | + } |
| 107 | +
|
| 108 | + type Author { |
| 109 | + id: ID! |
| 110 | + born: Int |
| 111 | + name: String! |
| 112 | + bookCount: Int! |
| 113 | + } |
| 114 | +
|
| 115 | + type Mutation { |
| 116 | + addBook(input: addBookInput): Book! |
| 117 | + editAuthor(input: editAuthorInput): Author |
| 118 | + } |
| 119 | +
|
| 120 | + input editAuthorInput { |
| 121 | + name: String! |
| 122 | + setBornTo: Int! |
| 123 | + } |
| 124 | +
|
| 125 | + input addBookInput { |
| 126 | + title: String! |
| 127 | + author: String! |
| 128 | + published: Int! |
| 129 | + genres: [String!]! |
| 130 | + } |
| 131 | +`; |
| 132 | + |
| 133 | +const resolvers = { |
| 134 | + Query: { |
| 135 | + bookCount: (_, args) => books.length, |
| 136 | + authorCount: (_, args) => authors.length, |
| 137 | + allBooks: (_, { name, genre }) => { |
| 138 | + let filteredBooks = books; |
| 139 | + if (name) { |
| 140 | + filteredBooks = filteredBooks.filter((book) => book.author === name); |
| 141 | + } |
| 142 | + |
| 143 | + if (genre) { |
| 144 | + filteredBooks = filteredBooks.filter((book) => |
| 145 | + book.genres.includes(genre) |
| 146 | + ); |
| 147 | + } |
| 148 | + return filteredBooks; |
| 149 | + }, |
| 150 | + allAuthors: () => authors, |
| 151 | + }, |
| 152 | + Author: { |
| 153 | + bookCount: (parent) => { |
| 154 | + const count = books.filter((book) => book.author === parent.name); |
| 155 | + return count.length; |
| 156 | + }, |
| 157 | + }, |
| 158 | + Mutation: { |
| 159 | + addBook: (_, { input }) => { |
| 160 | + const authorIndex = authors.findIndex( |
| 161 | + (author) => author.name === input.author |
| 162 | + ); |
| 163 | + const newBook = { |
| 164 | + id: Date.now(), |
| 165 | + ...input, |
| 166 | + }; |
| 167 | + if (authorIndex == -1) { |
| 168 | + authors.push({ id: Date.now(), name: input.author }); |
| 169 | + } |
| 170 | + books.push(newBook); |
| 171 | + return newBook; |
| 172 | + }, |
| 173 | + editAuthor: (_, { input }) => { |
| 174 | + const { name, setBornTo } = input; |
| 175 | + const index = authors.findIndex((author) => author.name === name); |
| 176 | + if (index == -1) return null; |
| 177 | + authors[index].born = setBornTo; |
| 178 | + return authors[index]; |
| 179 | + }, |
| 180 | + }, |
| 181 | +}; |
| 182 | + |
| 183 | +const server = new ApolloServer({ |
| 184 | + typeDefs, |
| 185 | + resolvers, |
| 186 | +}); |
| 187 | + |
| 188 | +server.listen().then(({ url }) => { |
| 189 | + console.log(`Server ready at ${url}`); |
| 190 | +}); |
0 commit comments