diff --git a/backend/ormconfig.json b/backend/ormconfig.json new file mode 100644 index 000000000..36c565344 --- /dev/null +++ b/backend/ormconfig.json @@ -0,0 +1,6 @@ +{ + "type": "sqlite", + "database": "./db.sqlite3", + "entities": ["./src/graphql/models/*.ts"], + "synchronize": true +} \ No newline at end of file diff --git a/backend/src/graphql/inputs/CreateBookInput.ts b/backend/src/graphql/inputs/CreateBookInput.ts new file mode 100644 index 000000000..8b3129a4a --- /dev/null +++ b/backend/src/graphql/inputs/CreateBookInput.ts @@ -0,0 +1,10 @@ +import { InputType, Field } from 'type-graphql' + +@InputType() +export class CreateBookInput { + @Field() + title: string; + + @Field() + author: string; +} diff --git a/backend/src/graphql/inputs/UpdateBookInput.ts b/backend/src/graphql/inputs/UpdateBookInput.ts new file mode 100644 index 000000000..12e11a39e --- /dev/null +++ b/backend/src/graphql/inputs/UpdateBookInput.ts @@ -0,0 +1,13 @@ +import { InputType, Field } from 'type-graphql' + +@InputType() +export class UpdateBookInput { + @Field({ nullable: true }) + title?: string; + + @Field({ nullable: true }) + author?: string; + + @Field({ nullable: true }) + isPublished?: boolean; +} \ No newline at end of file diff --git a/backend/src/graphql/models/Book.ts b/backend/src/graphql/models/Book.ts new file mode 100644 index 000000000..9fb15b001 --- /dev/null +++ b/backend/src/graphql/models/Book.ts @@ -0,0 +1,22 @@ +import { Entity, BaseEntity, PrimaryGeneratedColumn, Column } from 'typeorm' +import { ObjectType, Field, ID } from 'type-graphql' + +@Entity() +@ObjectType() +export class Book extends BaseEntity { + @Field(() => ID) + @PrimaryGeneratedColumn() + id: string; + + @Field(() => String) + @Column() + title: string; + + @Field(() => String) + @Column() + author: string; + + @Field(() => Boolean) + @Column({ default: false }) + isPublished: boolean; +} \ No newline at end of file diff --git a/backend/src/graphql/resolvers.ts b/backend/src/graphql/resolvers.ts deleted file mode 100644 index 4ad71d6e3..000000000 --- a/backend/src/graphql/resolvers.ts +++ /dev/null @@ -1 +0,0 @@ -export default [] \ No newline at end of file diff --git a/backend/src/graphql/resolvers/BookResolver.ts b/backend/src/graphql/resolvers/BookResolver.ts new file mode 100644 index 000000000..e301a69a7 --- /dev/null +++ b/backend/src/graphql/resolvers/BookResolver.ts @@ -0,0 +1,41 @@ +import { Resolver, Query, Mutation, Arg } from 'type-graphql' +import { Book } from '../models/Book' +import { CreateBookInput } from '../inputs/CreateBookInput' +import { UpdateBookInput } from '../inputs/UpdateBookInput' + +@Resolver() +export class BookResolver { + @Query(() => [Book]) + books() { + return Book.find(); + } + + @Query(() => Book) + book(@Arg("id") id: string) { + return Book.findOne({ where: { id } }); + } + + @Mutation(() => Book) + async createBook(@Arg("data") data: CreateBookInput) { + const book = Book.create(data); + await book.save(); + return book; + } + + @Mutation(() => Book) + async updateBook(@Arg("id") id: string, @Arg("data") data: UpdateBookInput) { + const book = await Book.findOne({ where: { id } }); + if (!book) throw new Error("Book not found!"); + Object.assign(book, data); + await book.save(); + return book; + } + + @Mutation(() => Boolean) + async deleteBook(@Arg("id") id: string) { + const book = await Book.findOne({ where: { id } }); + if (!book) throw new Error("Book not found!"); + await book.remove(); + return true; + } +} \ No newline at end of file diff --git a/backend/src/index.ts b/backend/src/index.ts index 5c02aeb14..7c265643b 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -3,15 +3,12 @@ import express from 'express' import { graphqlHTTP } from 'express-graphql' import { createConnection } from 'typeorm' import { buildSchema } from 'type-graphql' -// import resolvers from './graphql/resolvers' -const resolvers: [string] = [''] +import { BookResolver } from "./graphql/resolvers/BookResolver" // import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity"; async function main() { - //const connection = await createConnection() - const schema = await buildSchema({ - resolvers - }) + const connection = await createConnection() + const schema = await buildSchema({ resolvers: [BookResolver]}) const server = express(); server.use('/api', @@ -57,7 +54,7 @@ async function main() { // app.get("/playground", expressPlayground({ endpoint: "/graphql" })); server.listen(4000, () => { console.log( - `Server is running, GraphQL Playground available at http://localhost:4000/playground`, + `Server is running, GraphIQL available at http://localhost:4000/api`, ); }); } diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 64ec9cb7e..422ff8e0a 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -30,8 +30,7 @@ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // TODO: "strictPropertyInitialization": false - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + "strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */