{"id":16534638,"url":"https://github.com/hardyscc/nodejs-graphql-sample","last_synced_at":"2026-04-11T13:03:30.307Z","repository":{"id":43493026,"uuid":"274562040","full_name":"hardyscc/nodejs-graphql-sample","owner":"hardyscc","description":"Build a basic CRUD backend application in NodeJS with GraphQL \u0026 MySQL.","archived":false,"fork":false,"pushed_at":"2023-03-06T15:34:12.000Z","size":4163,"stargazers_count":3,"open_issues_count":12,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T05:23:18.655Z","etag":null,"topics":["graphql","graphql-playground","mysql","nestjs","nodejs","typeorm","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hardyscc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-24T03:05:41.000Z","updated_at":"2023-12-09T07:46:51.000Z","dependencies_parsed_at":"2024-12-18T00:23:10.170Z","dependency_job_id":"a2ae239f-8b84-48b3-ac6a-1ae7e6700d85","html_url":"https://github.com/hardyscc/nodejs-graphql-sample","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardyscc%2Fnodejs-graphql-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardyscc%2Fnodejs-graphql-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardyscc%2Fnodejs-graphql-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardyscc%2Fnodejs-graphql-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hardyscc","download_url":"https://codeload.github.com/hardyscc/nodejs-graphql-sample/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249600,"owners_count":20908211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-playground","mysql","nestjs","nodejs","typeorm","typescript"],"created_at":"2024-10-11T18:24:51.801Z","updated_at":"2025-12-30T23:08:15.393Z","avatar_url":"https://github.com/hardyscc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NodeJS GraphQL Backend Tutorial\n\n## Overview\n\nBuild a basic CRUD backend application in NodeJS with GraphQL \u0026 MySQL.\n\n## Technologies\n\n1. [NodeJS](https://nodejs.org/)\n1. [TypeScript](https://www.typescriptlang.org/)\n1. [NestJS](https://nestjs.com/)\n1. [TypeGraphQL](https://typegraphql.com/)\n1. [TypeORM](https://typeorm.io/)\n1. [MySQL](https://www.mysql.com/)\n\n## Create an Empty Project\n\nSetup an empty project using [Nest CLI](https://docs.nestjs.com/cli/overview).\n\n```bash\nnpm install -g @nestjs/cli\nnest new nodejs-graphql-sample\ncd nodejs-graphql-sample\n```\n\n\u003e Please use `npm` as the default package manager for this tutorial.\n\n\u003e For more information, please see [NestJS First Steps](https://docs.nestjs.com/first-steps).\n\nStart the server in watch mode.\n\n```bash\nnpm run start:dev\n```\n\nGoto http://localhost:3000 You should see the `Hello World` message.\n\n## NestJS GraphQL Module\n\n### Install and Config\n\nInstall the required packages.\n\n```bash\nnpm install @nestjs/graphql graphql-tools graphql apollo-server-express type-graphql\n```\n\nUpdate the `src/app.module.ts` as follow.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { GraphQLModule } from '@nestjs/graphql';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\n\n@Module({\n  imports: [\n    GraphQLModule.forRoot({\n      autoSchemaFile: true,\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nUpdate the `src/main.ts` to accept the `PORT` environment variable.\n\n```ts\nasync function bootstrap() {\n  ...\n  await app.listen(process.env.PORT || 4000);\n}\n...\n```\n\n\u003e Notes that the default backend port has been changed to `4000` as well, to avoid the port conflict with frontend.\n\n### Generate the Skeleton Template for User Module and Resolver\n\n```bash\nnest generate module user\nnest generate resolver user --no-spec\n```\n\nThe following folder and files will be created.\n\n```sh\nsrc/user/user.resolver.ts\nsrc/user/user.module.ts\n```\n\nPlease notes that `src/app.module.ts` also updated automatically as follow.\n\n```ts\n...\nimport { UserModule } from './user/user.module';\n\n@Module({\n  imports: [\n    ...\n    UserModule,\n  ],\n  ...\n})\nexport class AppModule {}\n\n```\n\n### Create the User Entity and Input Type\n\nCreate the following file `src/user/user.entity.ts`.\n\n```ts\nimport { Field, ID, ObjectType } from '@nestjs/graphql';\n\n@ObjectType()\nexport class User {\n  @Field(() =\u003e ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field({ nullable: true })\n  nickName?: string;\n}\n```\n\nCreate the following file `src/user/create-user.input.ts`.\n\n```ts\nimport { Field, InputType } from '@nestjs/graphql';\n\n@InputType()\nexport class CreateUserInput {\n  @Field()\n  name: string;\n\n  @Field({ nullable: true })\n  nickName?: string;\n}\n```\n\n### Implement the User Resolver\n\nUpdate `src/user/user.resolver.ts` and add the `users` query and `createUser` mutation.\n\n```ts\nimport { Args, Mutation, Query, Resolver } from '@nestjs/graphql';\nimport { CreateUserInput } from './create-user.input';\nimport { User } from './user.entity';\n\nconst users: User[] = [];\n\n@Resolver('User')\nexport class UserResolver {\n  @Mutation(() =\u003e User)\n  createUser(@Args('input') input: CreateUserInput) {\n    const user = new User();\n    user.name = input.name;\n    user.nickName = input.nickName;\n    user.id = String(Math.floor(Math.random() * 1000000000));\n    users.push(user);\n    return user;\n  }\n\n  @Query(() =\u003e [User])\n  users() {\n    return users;\n  }\n}\n```\n\n\u003e just temporary keep the users list in memory, will change to use database later.\n\n### Test the GraphQL Endpoint\n\nStart the server instance in watch mode.\n\n```bash\nnpm run start:dev\n```\n\nGoto the GraphQL Playground - http://localhost:4000/graphql.\n\n1. Create a new user\n\n   ```graphql\n   mutation {\n     createUser(input: { name: \"Tommy\" }) {\n       id\n     }\n   }\n   ```\n\n   Output :\n\n   ```json\n   {\n     \"data\": {\n       \"createUser\": {\n         \"id\": \"95678594\"\n       }\n     }\n   }\n   ```\n\n2. Query the users\n\n   ```graphql\n   query {\n     users {\n       id\n       name\n     }\n   }\n   ```\n\n   Output :\n\n   ```json\n   {\n     \"data\": {\n       \"users\": [\n         {\n           \"id\": \"95678594\",\n           \"name\": \"Tommy\"\n         }\n       ]\n     }\n   }\n   ```\n\n## NestJS TypeORM Module\n\n### Install and Config\n\nInstall the required packages.\n\n```bash\nnpm install @nestjs/typeorm typeorm mysql2\n```\n\nAdd the TypeOrmModule Configuration into `src/app.module.ts` as follow.\n\n```ts\n...\nimport { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { User } from \"./user/user.entity\";\n...\n\nconst databaseUrl =\n  process.env.DATABASE_URL ||\n  'mysql://usr:User12345@localhost:3306/development';\n\n@Module({\n  imports: [\n    ...\n    TypeOrmModule.forRoot({\n      type: 'mysql',\n      url: databaseUrl,\n      database: databaseUrl.split('/').pop(),\n      entities: [User],\n      synchronize: true,\n      logging: true,\n    }),\n    ...\n  ]\n})\nexport class AppModule {}\n```\n\nAdd the TypeOrmModule Configuration into `src/user/user.module.ts` as follow.\n\n```ts\n...\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport { User } from \"./user.entity\";\n...\n\n@Module({\n  imports: [TypeOrmModule.forFeature([User])],\n  ...\n})\nexport class UserModule {}\n```\n\n\u003e for more information, please see [NestJS Database](https://docs.nestjs.com/techniques/database).\n\n### Add the TypeORM Decorators into User Entity\n\nUpdate the following file `src/user/user.entity.ts`.\n\n```ts\nimport { Field, ID, ObjectType } from '@nestjs/graphql';\nimport { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';\n\n@ObjectType()\n@Entity()\nexport class User {\n  @Field(() =\u003e ID)\n  @PrimaryGeneratedColumn('uuid')\n  id: string;\n\n  @Field()\n  @Column()\n  name: string;\n\n  @Field({ nullable: true })\n  @Column({ nullable: true })\n  nickName?: string;\n}\n```\n\n### Create an User Service\n\nThis is a helper service which using `TypeORM's Repository API` to access the MySQL database.\n\n```\nnest generate service user --no-spec\n```\n\nUpdate the generated file `src/user/user.service.ts` as follow.\n\n```ts\nimport { Injectable } from '@nestjs/common';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { Repository } from 'typeorm';\nimport { CreateUserInput } from './create-user.input';\nimport { User } from './user.entity';\n\n@Injectable()\nexport class UserService {\n  constructor(\n    @InjectRepository(User)\n    private readonly userRepository: Repository\u003cUser\u003e,\n  ) {}\n\n  create(input: CreateUserInput) {\n    const user = this.userRepository.create(input);\n    return this.userRepository.save(user);\n  }\n\n  findOneById(id: string) {\n    return this.userRepository.findOneOrFail(id);\n  }\n\n  async delete(id: string) {\n    const { affected } = await this.userRepository.delete(id);\n    return affected !== 0;\n  }\n\n  find() {\n    return this.userRepository.find();\n  }\n}\n```\n\n### Update the User Resolver\n\nUpdate the following file `src/user/user.resolver.ts`.\n\n```ts\nimport { NotFoundException } from '@nestjs/common';\nimport { Args, Mutation, Query, Resolver, ID } from '@nestjs/graphql';\nimport { CreateUserInput } from './create-user.input';\nimport { User } from './user.entity';\nimport { UserService } from './user.service';\n\n@Resolver(User)\nexport class UserResolver {\n  constructor(private readonly userService: UserService) {}\n\n  @Query(() =\u003e User)\n  async user(@Args({ name: 'id', type: () =\u003e ID }) id: string) {\n    const user = await this.userService.findOneById(id);\n    if (!user) {\n      throw new NotFoundException(id);\n    }\n    return user;\n  }\n\n  @Mutation(() =\u003e User)\n  createUser(@Args('input') input: CreateUserInput) {\n    return this.userService.create(input);\n  }\n\n  @Mutation(() =\u003e ID, { nullable: true })\n  async deleteUser(@Args({ name: 'id', type: () =\u003e ID }) id: string) {\n    return (await this.userService.delete(id)) ? id : null;\n  }\n\n  @Query(() =\u003e [User])\n  users() {\n    return this.userService.find();\n  }\n}\n```\n\n### Test the GraphQL Endpoint with TypeORM\n\nStart a MySQL docker instance.\n\n```bash\ndocker run -d -e \"MYSQL_ROOT_PASSWORD=Admin12345\" -e \"MYSQL_USER=usr\" -e \"MYSQL_PASSWORD=User12345\" -e \"MYSQL_DATABASE=development\" -p 3306:3306 --name some-mysql bitnami/mysql:5.7.27\n```\n\nStart the server instance in watch mode.\n\n```bash\nnpm run start:dev\n```\n\nGoto the GraphQL Playground - http://localhost:4000/graphql.\n\n1. Create some users\n\n   ```graphql\n   mutation {\n     a: createUser(input: { name: \"John\" }) {\n       id\n     }\n     b: createUser(input: { name: \"Mary\" }) {\n       id\n     }\n   }\n   ```\n\n   Output:\n\n   ```json\n   {\n     \"data\": {\n       \"a\": {\n         \"id\": \"6ad2b68d-15a8-4e3e-9062-6343324faa7e\"\n       },\n       \"b\": {\n         \"id\": \"eb777cfa-65d4-4a36-9344-5452284647e6\"\n       }\n     }\n   }\n   ```\n\n2. Query the users\n\n   ```graphql\n   query {\n     users {\n       id\n       name\n     }\n   }\n   ```\n\n   Output :\n\n   ```json\n   {\n     \"data\": {\n       \"users\": [\n         {\n           \"id\": \"6ad2b68d-15a8-4e3e-9062-6343324faa7e\",\n           \"name\": \"John\"\n         },\n         {\n           \"id\": \"eb777cfa-65d4-4a36-9344-5452284647e6\",\n           \"name\": \"Mary\"\n         }\n       ]\n     }\n   }\n   ```\n\n3. Delete one of the user by the id\n\n   ```graphql\n   mutation {\n     deleteUser(id: \"6ad2b68d-15a8-4e3e-9062-6343324faa7e\")\n   }\n   ```\n\n   Output :\n\n   ```json\n   {\n     \"data\": {\n       \"deleteUser\": \"6ad2b68d-15a8-4e3e-9062-6343324faa7e\"\n     }\n   }\n   ```\n\n4. Test the MySQL database\n\n   Run the mysql command using the same docker instance.\n\n   ```bash\n   docker exec -it some-mysql mysql -uroot -p\"Admin12345\"\n   ```\n\n   Select the data from user table.\n\n   ```sql\n   mysql\u003e use development;\n   mysql\u003e select * from user;\n   +--------------------------------------+------+----------+\n   | id                                   | name | nickName |\n   +--------------------------------------+------+----------+\n   | eb777cfa-65d4-4a36-9344-5452284647e6 | Mary | NULL     |\n   +--------------------------------------+------+----------+\n   ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhardyscc%2Fnodejs-graphql-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhardyscc%2Fnodejs-graphql-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhardyscc%2Fnodejs-graphql-sample/lists"}