{"id":27288354,"url":"https://github.com/darinelescobar/graphql-template-hexagonal-architecture","last_synced_at":"2026-04-15T10:37:33.126Z","repository":{"id":287294371,"uuid":"964261008","full_name":"DarinelEscobar/graphql-template-hexagonal-architecture","owner":"DarinelEscobar","description":"A boilerplate to kickstart GraphQL APIs using NestJS, Prisma, and MySQL. Includes Docker setup, Prisma migrations and client generation, and an example seed script. Perfect for quickly launching clean, scalable backend projects.","archived":false,"fork":false,"pushed_at":"2025-04-11T00:08:39.000Z","size":125,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T01:20:30.602Z","etag":null,"topics":["api","backend","boilerplate","clean-architecture","db-migration","docker","graphql","hexagonal-architecture","mysql","nestjs","prisma","template","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/DarinelEscobar.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,"zenodo":null}},"created_at":"2025-04-11T00:01:03.000Z","updated_at":"2025-04-11T01:15:19.000Z","dependencies_parsed_at":"2025-04-11T01:20:41.402Z","dependency_job_id":"60710c33-2f20-4f29-ae26-61eaefd70e5b","html_url":"https://github.com/DarinelEscobar/graphql-template-hexagonal-architecture","commit_stats":null,"previous_names":["darinelescobar/graphql-template"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinelEscobar%2Fgraphql-template-hexagonal-architecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinelEscobar%2Fgraphql-template-hexagonal-architecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinelEscobar%2Fgraphql-template-hexagonal-architecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinelEscobar%2Fgraphql-template-hexagonal-architecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DarinelEscobar","download_url":"https://codeload.github.com/DarinelEscobar/graphql-template-hexagonal-architecture/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480326,"owners_count":21110935,"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":["api","backend","boilerplate","clean-architecture","db-migration","docker","graphql","hexagonal-architecture","mysql","nestjs","prisma","template","typescript"],"created_at":"2025-04-11T20:46:04.032Z","updated_at":"2026-04-15T10:37:33.113Z","avatar_url":"https://github.com/DarinelEscobar.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://nestjs.com/\" target=\"blank\"\u003e\n    \u003cimg src=\"https://nestjs.com/img/logo-small.svg\" width=\"120\" alt=\"Nest Logo\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# GraphQL API Template with NestJS, Prisma, and MySQL\n\nThis project is a boilerplate to build a GraphQL API using NestJS and Prisma, connected to a MySQL database. It includes a Docker setup for the database and an example `seed` script for initial data population.\n\n---\n\n\n## 🔥 Features (Updated)\n\n- ✅ JWT Authentication (Access + Refresh Tokens)\n- ✅ Role-Based Access Control using `@Roles` decorator and `RolesGuard`\n- ✅ Create Account and Login mutations with secure password hashing (bcrypt)\n- ✅ Refresh Token Mutation\n- ✅ Public GraphQL Queries: `users`, `user(id)`\n- ✅ Protected Queries:\n  - `products`: Requires `CHEF` role\n  - `productsByUser`: Requires `USER` or `CHEF` role\n- ✅ Global Rate Limiting via Throttler (custom `GqlThrottlerGuard`)\n\n\n## Prerequisites\n\n- [Node.js](https://nodejs.org/en/) (recommended LTS version, 16+)\n- [Nest CLI](https://docs.nestjs.com/cli/overview) (optional, for quick scaffolding)\n- [Docker and Docker Compose](https://docs.docker.com/compose/) (for the MySQL database)\n- [MySQL Workbench](https://www.mysql.com/products/workbench/) or any other DB GUI tool (optional)\n\n---\n\n## Folder Structure (Example)\n\n```\ngraphql-api-template\n├── docker-compose.yml\n├── .env\n├── package.json\n├── prisma\n│   ├── schema.prisma\n│   └── seed.ts\n├── src\n│   ├── app.module.ts\n│   ├── main.ts\n│   └── user\n│       ├── user.module.ts\n│       ├── user.resolver.ts\n│       ├── user.service.ts\n│       └── user.type.ts\n├── tsconfig.json\n└── ...\n```\n\n---\n\n## Environment Variables\n\nIn the root directory, create a `.env` file with your database connection URL, for example:\n\n```bash\nDATABASE_URL=\"mysql://root:@localhost:3306/graphql-db\"\n```\n\n---\n\n\n\n\n## Prisma Setup\n\n### 1. Define the schema in prisma/schema.prisma\n\n```prisma \n\ndatasource db {\n  provider = \"mysql\"\n  url      = env(\"DATABASE_URL\")\n}\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\nmodel User {\n  id        Int      @id @default(autoincrement())\n  name      String\n  email     String   @unique\n  password  String\n  rol       String   @default(\"USER\")  \n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n\n  products  Product[]\n}\n\nmodel Product {\n  id        Int      @id @default(autoincrement())\n  name      String\n  userId    Int\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n\n  user      User     @relation(fields: [userId], references: [id])\n}\n\n\n\n```\n\n### 2. Run Database Migration\n\n```bash\nnpx prisma migrate dev --name init\n```\n\n### 3. Generate Prisma Client\n\n```bash\nnpx prisma generate\n```\n\n### 4. Seed Initial Data\n\n**prisma/seed.ts**\n```ts\nimport { PrismaClient } from '@prisma/client'\nimport * as bcrypt from 'bcryptjs'\n\nconst prisma = new PrismaClient()\n\nasync function main() {\n  const salt = await bcrypt.genSalt(10)\n\n  const user = await prisma.user.create({\n    data: {\n      name: 'Juan Pérez',\n      email: 's@user.com',\n      password: await bcrypt.hash('12', salt),\n      rol: 'USER',\n    },\n  })\n\n  const chef = await prisma.user.create({\n    data: {\n      name: 'María Cocina',\n      email: 's@chef.com',\n      password: await bcrypt.hash('12', salt),\n      rol: 'CHEF',\n    },\n  })\n\n  await prisma.product.createMany({\n    data: [\n      { name: 'Taco Supremo', userId: user.id },\n      { name: 'Burrito Deluxe', userId: user.id },\n      { name: 'Paella Gourmet', userId: chef.id },\n      { name: 'Sopa Azteca', userId: chef.id },\n    ],\n  })\n}\n\nmain()\n  .catch((e) =\u003e {\n    console.error(e)\n    process.exit(1)\n  })\n  .finally(async () =\u003e {\n    await prisma.$disconnect()\n  })\n\n```\n\nRun the seed:\n\n```bash\nnpx ts-node prisma/seed.ts\n```\n\n---\n\n## Project Setup\n\n```bash\nnpm install\n```\n\n---\n\n## Run the Project\n\n```bash\n# development\nnpm run start\n\n# watch mode\nnpm run start:dev\n\n# production\nnpm run start:prod\n```\n\nThe app will be running at `http://localhost:3000`.\n\n---\n## GraphQL Playground\n\nGo to `http://localhost:3000/graphql`.\n\n---\n\n## Example Auth Mutations\n\n### 🚀 Create Account\n\n```graphql\nmutation {\n  createAccount(data: { name: \"Juan\", email: \"juan@example.com\", password: \"1234\" }) {\n    accessToken\n    userId\n    rol\n    refreshToken\n  }\n}\n```\n\n### 🔐 Login\n\n```graphql\nmutation {\n  login(data: { email: \"juan@example.com\", password: \"1234\" }) {\n    accessToken\n    userId\n    rol\n    refreshToken\n  }\n}\n```\n\n### 🔄 Refresh Token\n\n```graphql\nmutation {\n  refreshToken(refreshToken: \"yourRefreshTokenHere\") {\n    accessToken\n    userId\n    rol\n    refreshToken\n  }\n}\n```\n\n## Role-based GraphQL Query Protection\n\n| Query              | Roles Required | Description                         |\n|-------------------|----------------|-------------------------------------|\n| `users`           | ❌ Public      | Get all users                       |\n| `user(id)`        | ❌ Public      | Get user by ID                      |\n| `products`        | ✅ CHEF only   | Get all products                    |\n| `productsByUser`  | ✅ USER, CHEF  | Get products by user ID             |\n\n\u003e ⚠️ `products` and `productsByUser` require an `Authorization` header with a valid token. Don’t even try without it:\n```json\n{\n  \"Authorization\": \"Bearer YOUR_ACCESS_TOKEN\"\n}\n```\n\n---\n\n## Run Tests\n\n```bash\n# unit tests\nnpm run test\n\n# e2e tests\nnpm run test:e2e\n\n# test coverage\nnpm run test:cov\n```\n\n---\n\n## Deployment\n\n```bash\nnpm install -g @nestjs/mau\nmau deploy\n```\n\n---\n\n## Final Notes\n\nMake sure to customize the `.env` configuration and never commit sensitive credentials. For production, use secret management tools and containerize the API if needed alongside the DB.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarinelescobar%2Fgraphql-template-hexagonal-architecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarinelescobar%2Fgraphql-template-hexagonal-architecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarinelescobar%2Fgraphql-template-hexagonal-architecture/lists"}