{"id":21065811,"url":"https://github.com/washira/next-prisma-app","last_synced_at":"2026-05-04T01:32:50.591Z","repository":{"id":224464255,"uuid":"763321229","full_name":"Washira/next-prisma-app","owner":"Washira","description":"Next.js 14 and Prisma using with Postgresql into container started from Docker-compose.","archived":false,"fork":false,"pushed_at":"2024-03-07T02:55:55.000Z","size":93,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-20T21:12:50.781Z","etag":null,"topics":["docker-compose","nextjs14","postgresql","prisma","tailwindcss","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/Washira.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":"2024-02-26T04:20:01.000Z","updated_at":"2024-03-06T03:09:14.000Z","dependencies_parsed_at":"2024-11-19T17:56:39.379Z","dependency_job_id":"be44ac6f-b7e6-49ef-8f77-e159cd577051","html_url":"https://github.com/Washira/next-prisma-app","commit_stats":null,"previous_names":["washira/next-prisma-app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washira%2Fnext-prisma-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washira%2Fnext-prisma-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washira%2Fnext-prisma-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washira%2Fnext-prisma-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Washira","download_url":"https://codeload.github.com/Washira/next-prisma-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243510002,"owners_count":20302294,"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":["docker-compose","nextjs14","postgresql","prisma","tailwindcss","typescript"],"created_at":"2024-11-19T17:56:31.028Z","updated_at":"2026-05-04T01:32:45.552Z","avatar_url":"https://github.com/Washira.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).\n\n- [Getting Started](#getting-started)\n- [Learn More](#learn-more)\n- [Deploy on Vercel](#deploy-on-vercel)\n- [Configuration](#configuration)\n- [Installation](#installation)\n  - [Docker Compose](#docker-compose)\n  - [Prisma](#prisma)\n    - [ติดตั้ง Prisma ด้วย](#ติดตั้ง-prisma-ด้วย)\n    - [Setting](#setting)\n    - [สร้าง Migration](#สร้าง-migration)\n    - [เพิ่ม Migration ใหม่](#เพิ่ม-migration-ใหม่)\n- [Create APIs](#create-apis)\n  - [method ที่ใช้](#method-ที่ใช้)\n    - [Static route](#static-route)\n    - [Dynamic route](#dynamic-route)\n- [Frontend](#frontend)\n- [ปรับ APIs เพื่อให้ Search และ Filter ได้](#ปรับ-apis-เพื่อให้-search-และ-filter-ได้)\n  - [ใช้ `NextRequest` ในการรับค่าจาก query string](#ใช้-nextrequest-ในการรับค่าจาก-query-string)\n- [ทำ CRUD API ของ Category](#ทำ-crud-api-ของ-category)\n\n\n## Getting Started\n\nFirst, run the development server:\n\n```bash\nnpm run dev\n# or\nyarn dev\n# or\npnpm dev\n# or\nbun dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n\nYou can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.\n\nThis project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.\n\n## Learn More\n\nTo learn more about Next.js, take a look at the following resources:\n\n- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.\n- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.\n\nYou can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!\n\n## Deploy on Vercel\n\nThe easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template\u0026filter=next.js\u0026utm_source=create-next-app\u0026utm_campaign=create-next-app-readme) from the creators of Next.js.\n\nCheck out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.\n\n## Configuration\n\nเมื่อสร้างโปรเจคใหม่ ให้ตอบคำถามตามนี้\n\n```bash\nWhat is your project named? … next-prisma-app\n✔ Would you like to use TypeScript? … Yes\n✔ Would you like to use ESLint? … No\n✔ Would you like to use Tailwind CSS? … Yes\n✔ Would you like to use `src/` directory? … No\n✔ Would you like to use App Router? (recommended) … Yes\n✔ Would you like to customize the default import alias (@/*)? … Yes\n✔ What import alias would you like configured? … @/*\n```\n\n## Installation\n\n### Docker Compose\n\nรันคำสั่ง `docker-compose up -d`\n\n### Prisma\n\n#### ติดตั้ง Prisma ด้วย\n\n```bash\nnpm install prisma --save-dev\nnpm install @prisma/client\n```\n\nสร้างไฟล์เริ่มต้นของ Prisma\n\n```bash\nnpx prisma init\n```\n\n#### Setting\n\nเปลี่ยน `DATABASE_URL` ใน `.env` ให้ตรงกับ username, password ของ database ของเรา\n\n#### สร้าง Migration\n\nMigration คือ version control ของ database\n\nสร้าง Migration สำหรับ database ด้วย\n\n```bash\nnpx prisma migrate dev --name \u003cMIGRATE_NAME\u003e\n```\n\nยกตัวอย่าง เช่น `npx prisma migrate dev --name \"Create Post Table\"`\n\nจะได้ folder ที่เป็น migration ใน `prisma/migrations` folder ชื่อว่า `\u003ctime_stamp\u003e_create_post_table` และ ไฟล์ `migration_lock.toml`\n\n#### เพิ่ม Migration ใหม่\n\nมี 2 วิธีในการเพิ่ม migration ใหม่ คือ\n\n1. ถ้าต้องการเพิ่ม field ที่ไม่มี value ด้วย ให้เพิ่ม field ใน `schema.prisma` และสร้าง migration ใหม่ อาจจะให้ field นั้นเป็น `null` โดยการใส่ `?` หลังชื่อ field ใน `schema.prisma` เช่น\n\n```prisma\nmodel Post {\n  id        Int      @id @default(autoincrement())\n  title     String\n  content   String?\n  category string? // เพิ่ม field ใหม่ สามารถเป็น null ได้\n  createdAt DateTime @default(now())\n}\n```\n\nแล้วรันคำสั่ง `npx prisma migrate dev --name \u003cMIGRATE_NAME\u003e` อีกครั้ง\n\n2. ถ้าต้องการเพิ่ม field ที่มี value ด้วย ให้เพิ่ม field ใน `schema.prisma` และสร้าง migration ใหม่ ให้เพิ่ม `--create-only` ด้วย\n\n```bash\nnpx prisma migrate dev --name \u003cMIGRATE_NAME\u003e --create-only\n```\n\nจะมีการถามให้ยืนยันการสร้าง migration\n\n```bash\n✔ Are you sure you want to create this migration? … yes\n```\n\nเนื่องจากเราใช้ `--create-only` จะไม่มีการสร้าง field ใหม่ใน database จริง ๆ แต่จะสร้าง migration ใหม่ใน `prisma/migrations` folder เท่านั้น ทำให้เราต้องรัน `npx prisma migrate dev` อีกครั้งเพื่อทำการสร้าง field ใหม่ใน database\n\n```bash\nnpx prisma migrate dev\n```\n\nแต่จะมี error เพราะว่ามี field ที่ไม่มีค่าใน database ให้เราทำการเพิ่มค่าให้กับ field ที่เพิ่มใหม่ และรัน `npx prisma migrate dev` อีกครั้ง\n\nหลังจากนั่้น จะมีข้อความให้ยืนยันว่า เรายอมรับที่ข้อมูลจะถูกลบทั้งหมด\n\n```bash\nDo you want to continue? All data will be lost. … yes\n```\n\nจากนั้นจะมีการสร้าง migration ใหม่ และ field ใหม่จะถูกเพิ่มใน database\n\n## Create APIs\n\nสร้าง APIs ด้วย Prisma Client ใน `api` folder\n\nLayout ของ APIs จะเป็นแบบนี้\n  \n```\napi\n├── posts\n│   ├── [id]\n│   │   └── route.ts\n│   └── route.ts\n└── users\n    ├── [id]\n    │   └── route.ts\n    └── route.ts\n```\n\n### method ที่ใช้\n\nแบ่งเป็น 2 แบบคือ Static route และ Dynamic route\n\n#### Static route\n\nใน app สร้าง `api/posts/route.ts` เป็น folder สำหรับเก็บ APIs ที่เกี่ยวกับ Post\n\n- `GET` `api/posts` สำหรับดึงข้อมูล: สร้าง function `GET()`\n- `POST` `api/posts` สำหรับสร้างข้อมูล: สร้าง function `POST()`\n\n#### Dynamic route\n\nสร้าง folder `api/posts/[id]/routs.ts` สำหรับเก็บ APIs ที่เกี่ยวกับ Post ตาม id\n\n- `GET` `api/posts/:id` สำหรับดึงข้อมูลตาม id: สร้าง function `GET()`\n- `PUT` `api/posts/:id` สำหรับแก้ไขข้อมูลตาม id: สร้าง function `PUT()`\n- `DELETE` `api/posts/:id` สำหรับลบข้อมูลตาม id: สร้าง function `DELETE()`\n\n## Frontend\n\nLayout ของ Frontend จะประกอบไปด้วย\n\n```\n├── app\n    ├── api --\u003e API จากส่วนก่อนหน้านี้\n    │   └── posts\n    │       ├── [id]\n    │       │   └── route.ts\n    │       └── route.ts\n    ├── components\n    │   └── PostForm.tsx\n    ├── create\n    │   └── page.tsx\n    ├── edit\n    │   └── [id]\n    │       └── page.tsx\n    └── page.tsx\n```\n\n- `app/components` สำหรับเก็บ component ที่ใช้ซ้ำ\n- `app/components/PostForm.tsx` สำหรับเก็บ form สำหรับสร้างและแก้ไขข้อมูล\n- `app/create` คือ page สำหรับสร้างข้อมูล\n- `app/create/page.tsx` สำหรับเก็บ page สำหรับสร้างข้อมูล\n- `app/edit` คือ page สำหรับแก้ไขข้อมูล\n- `app/edit/[id]/page.tsx` คือ page สำหรับแก้ไขข้อมูล ตาม id\n- `app/page.tsx` สำหรับเก็บ page หลัก\n\n## ปรับ APIs เพื่อให้ Search และ Filter ได้\n\nเพิ่ม function สำหรับ search และ filter ใน `api/posts/route.ts`\n\n### ใช้ `NextRequest` ในการรับค่าจาก query string\n\nใช้ `NextRequest` ที่เป็น interface ในการรับค่าจาก query string\n\n```ts\nimport { NextRequest } from 'next/server'\n\nexport default async function GET(req: NextRequest) {\n  const searchParams = request.nextUrl.searchParams\n  const search = searchParams.get('search') // ทำการรับ search จาก query string\n  const filter = searchParams.get('filter')\n  // ทำการ filter ข้อมูลตาม search และ filter\n  const posts = await prisma.post.findMany({\n    where: {\n      title: {\n        contains: search, // ค้นหา post ที่มี search เป็น substring ใน title\n        mode: 'insensitive', // ไม่สนใจตัวเล็กตัวใหญ่\n      },\n    }\n  })\n  return posts\n}\n```\n\n## ทำ CRUD API ของ Category\n\nสร้าง APIs สำหรับ Category ใน `api/categories/route.ts`\n\n```\n├── app\n    ├── api\n        ├── categories --\u003e ส่วนที่เพิ่มเข้ามา\n        │   ├── [id]\n        │   │   └── route.ts\n        │   └── route.ts\n        └── posts\n            ├── [id]\n            │   └── route.ts\n            └── route.ts\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwashira%2Fnext-prisma-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwashira%2Fnext-prisma-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwashira%2Fnext-prisma-app/lists"}