Share

Xây dựng API CRUD với Node.js và Supabase – Hướng dẫn chi tiết cho người mới bắt đầu

Xây Dựng API CRUD Với Node.js và Supabase - Hướng Dẫn Chi Tiết Cho Người Mới Bắt Đầu

Bạn cảm thấy mệt mỏi với việc thiết lập cơ sở dữ liệu và xây dựng API từ đầu? Bạn đang tìm kiếm cách xây dựng một API đơn giản nhưng mạnh mẽ cho ứng dụng web của mình, bài viết này chính là dành cho bạn! Hôm nay, chúng ta sẽ cùng nhau khám phá cách tạo một RESTful API đầy đủ chức năng sử dụng bộ đôi Node.js và Supabase – một giải pháp BaaS (Backend-as-a-Service) đang rất hot hiện nay.

Supabase là gì và tại sao nên dùng?

Nếu bạn đã từng làm việc với Firebase, thì Supabase chính là “người anh em” mã nguồn mở của nó. Supabase cung cấp cho chúng ta một PostgreSQL database với khả năng real-time, hệ thống authentication có sẵn, storage để lưu trữ file, và đặc biệt là auto-generated API – điều này giúp chúng ta tiết kiệm rất nhiều thời gian khi làm việc với database.

Điểm mạnh của Supabase là gì? Đó chính là việc bạn được sử dụng sức mạnh của PostgreSQL (một trong những hệ quản trị cơ sở dữ liệu quan hệ mạnh mẽ nhất) kết hợp với JavaScript SDK dễ sử dụng. Quá hời phải không nào?

Tại Sao Nên Kết Hợp Node.js Với Supabase?

Khi kết hợp với Node.js và Express.js, bạn có được một tech stack hoàn hảo để xây dựng API với các thao tác CRUD một cách nhanh chóng và hiệu quả.

Những Lợi Ích Chính Của Supabase:

  • PostgreSQL Database: Cơ sở dữ liệu mạnh mẽ với khả năng real-time
  • Authentication có sẵn: Quên đi nỗi đau về việc xây dựng hệ thống xác thực
  • Storage: Lưu trữ và quản lý file dễ dàng
  • Auto-generated APIs: Tiết kiệm thời gian với các API được tạo tự động
  • Pricing hợp lý: Miễn phí cho các dự án nhỏ và cá nhân

Chuẩn Bị Công Cụ và Môi Trường

Trước khi bắt tay vào code, hãy điểm qua các công nghệ chúng ta sẽ sử dụng:

  • Node.js: Môi trường runtime JavaScript server-side
  • Express.js: Framework web nhẹ nhưng mạnh mẽ cho Node.js
  • Supabase: Tài khoản và project đã được tạo
  • dotenv: Để quản lý biến môi trường một cách an toàn
  • Swagger: Công cụ tuyệt vời để tạo tài liệu API

Bắt Đầu Xây Dựng Project

Bước 1: Khởi tạo dự án

Đầu tiên, hãy tạo một thư mục mới và khởi tạo dự án Node.js:

mkdir nodejs-supabase-api
cd nodejs-supabase-api
npm init -y

Bước 2: Cài đặt các dependencies cần thiết

npm install express @supabase/supabase-js dotenv cors swagger-ui-express swagger-jsdoc
npm install --save-dev nodemon

Bước 3: Thiết lập cấu trúc thư mục

Cấu trúc thư mục rõ ràng sẽ giúp dự án của bạn dễ quản lý hơn rất nhiều. Đây là cấu trúc mà tôi đề xuất:

nodejs-supabase-api
├── .env                  # Lưu trữ các biến môi trường
├── index.js              # Điểm khởi đầu ứng dụng
├── package.json          # Quản lý dependencies và scripts
├── config/
│   ├── supabaseClient.js # Cấu hình kết nối Supabase
│   └── swagger.js        # Cấu hình Swagger
├── controllers/
│   └── userController.js # Xử lý logic điều khiển
├── routes/
│   └── userRoutes.js     # Định nghĩa các route
└── services/
    └── userService.js    # Logic nghiệp vụ

Bước 4: Thiết lập file .env

Tạo file .env và thêm thông tin Supabase của bạn:

SUPABASE_URL=https://your-project-url.supabase.co
SUPABASE_KEY=your-anon-key
PORT=5000

Lấy URL và KEY ở đâu nhỉ? Đơn giản thôi, đăng ký tài khoản Supabase, tạo project mới và lấy URL cùng API key từ dashboard của bạn.

Kết Nối Với Supabase

Cấu hình Supabase Client: Đầu tiên, chúng ta cần thiết lập kết nối với Supabase.

Tạo file config/supabaseClient.js

import { createClient } from "@supabase/supabase-js";
import dotenv from "dotenv";

dotenv.config();

const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_KEY
);

export default supabase;

Triển Khai Các Thao Tác CRUD Cơ Bản

Bây giờ, hãy xây dựng các service để thực hiện các thao tác CRUD với bảng “users” trong database Supabase của chúng ta.

import supabase from '../config/supabaseClient.js';

// Tạo người dùng mới
export const createUser = async (userData) => {
  const { data, error } = await supabase
    .from("users")
    .insert([userData])
    .select();
  
  if (error) throw new Error(error.message);
  return data;
};

// Lấy danh sách người dùng
export const getUsers = async () => {
  const { data, error } = await supabase
    .from("users")
    .select("*");
  
  if (error) throw new Error(error.message);
  return data;
};

// Tìm người dùng theo ID
export const getUserById = async (id) => {
  const { data, error } = await supabase
    .from("users")
    .select("*")
    .eq("id", id)
    .single();
  
  if (error) throw new Error(error.message);
  return data;
};

// Cập nhật thông tin người dùng
export const updateUser = async (id, updates) => {
  const { data, error } = await supabase
    .from("users")
    .update(updates)
    .eq("id", id)
    .select();
  
  if (error) throw new Error(error.message);
  return data;
};

// Xóa người dùng
export const deleteUser = async (id) => {
  const { error } = await supabase
    .from("users")
    .delete()
    .eq("id", id);
  
  if (error) throw new Error(error.message);
  return { success: true, message: "Xóa người dùng thành công" };
};

Bạn thấy đấy, với Supabase, các thao tác với database trở nên vô cùng đơn giản và trực quan. Chỉ với vài dòng code, chúng ta đã có thể thực hiện đầy đủ các chức năng CRUD cơ bản.

Xây Dựng Controllers Và Routes

1. Tạo controllers/userController.js

Controllers sẽ kết nối giữa routes và services:

import * as userService from '../services/userService.js';

// Thêm người dùng mới
export const addUser = async (req, res) => {
  try {
    const data = await userService.createUser(req.body);
    res.status(201).json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Lấy danh sách người dùng
export const fetchUsers = async (req, res) => {
  try {
    const data = await userService.getUsers();
    res.status(200).json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Lấy thông tin người dùng theo ID
export const fetchUserById = async (req, res) => {
  try {
    const data = await userService.getUserById(req.params.id);
    if (!data) {
      return res.status(404).json({ message: "Không tìm thấy người dùng" });
    }
    res.status(200).json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Cập nhật thông tin người dùng
export const modifyUser = async (req, res) => {
  try {
    const data = await userService.updateUser(req.params.id, req.body);
    res.status(200).json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Xóa người dùng
export const removeUser = async (req, res) => {
  try {
    const result = await userService.deleteUser(req.params.id);
    res.status(200).json(result);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

2. Tạo routes/userRoutes.js

import express from "express";
import { 
  addUser, 
  fetchUsers, 
  fetchUserById, 
  modifyUser, 
  removeUser 
} from "../controllers/userController.js";

const router = express.Router();

// Tạo người dùng mới
router.post("/users", addUser);

// Lấy danh sách người dùng
router.get("/users", fetchUsers);

// Lấy thông tin người dùng theo ID
router.get("/users/:id", fetchUserById);

// Cập nhật thông tin người dùng
router.put("/users/:id", modifyUser);

// Xóa người dùng
router.delete("/users/:id", removeUser);

export default router;

Thiết lập Swagger để tạo API documentation

Swagger là một công cụ tuyệt vời để tạo tài liệu API. Việc này giúp đồng nghiệp hoặc người dùng của bạn dễ dàng hiểu và sử dụng API của bạn.

import swaggerJSDoc from 'swagger-jsdoc';

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'Node.js Supabase API',
      version: '1.0.0',
      description: 'A simple API built with Node.js, Express, and Supabase',
    },
    servers: [
      {
        url: 'http://localhost:8000',
        description: 'Development server',
      },
    ],
  },
  apis: ['./routes/*.js'],
};

const swaggerSpec = swaggerJSDoc(options);

export default swaggerSpec;

Khởi Động API Server

Tạo index.js

import express from 'express';
import dotenv from 'dotenv';
import cors from 'cors';
import swaggerUi from 'swagger-ui-express';
import swaggerSpec from './config/swagger.js';
import userRoutes from './routes/userRoutes.js';

// Cấu hình dotenv
dotenv.config();

const app = express();
const port = process.env.PORT || 8000;

// Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Swagger docs
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

// Routes
app.use('/api', userRoutes);

// Route mặc định
app.get('/', (req, res) => {
  res.send('Node.js Supabase API đang hoạt động!');
});

// Khởi động server
app.listen(port, () => {
  console.log(`Server đang chạy tại http://localhost:${port}`);
  console.log(`Tài liệu API: http://localhost:${port}/api-docs`);
});

Khởi chạy API và tạo tài liệu

Test API

Sau khi đã xây dựng xong API, chúng ta cần kiểm tra xem nó có hoạt động đúng không. Có thể sử dụng curl hoặc Postman, ở đây tôi sử dụng curl:

Tạo người dùng mới:

curl -X POST http://localhost:8000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Siu Code", "email": "admin@siucode.com", "age": 28}'

Lấy danh sách người dùng:

curl -X GET http://localhost:8000/api/users

Cập nhật thông tin người dùng:

curl -X PUT http://localhost:8000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "Siu Code Updated", "age": 29}'

Swagger API Documentation

Một điểm cộng lớn cho API của chúng ta là tài liệu tương tác. Để truy cập Swagger UI, hãy mở trình duyệt và truy cập:

http://localhost:8000/api-docs

Tại đây, bạn có thể xem tất cả các endpoints, thử nghiệm chúng và xem kết quả trả về mà không cần sử dụng công cụ bên ngoài như Postman. Quá tiện lợi phải không?

Những Điều Cần Lưu Ý

  1. Bảo mật: Supabase Key là bí mật, tuyệt đối không để lộ hoặc đặt trong các file công khai.
  2. Error Handling: Trong dự án thực tế, bạn nên có chiến lược xử lý lỗi toàn diện hơn.
  3. Validation: Thêm validation cho dữ liệu đầu vào để đảm bảo tính toàn vẹn của dữ liệu.
  4. Testing: Viết unit tests và integration tests cho API của bạn.

Kết Luận

Qua bài viết này, chúng ta đã xây dựng thành công một RESTful API đơn giản nhưng đầy đủ chức năng sử dụng Node.js, Express.js và Supabase. Điều tuyệt vời là chúng ta đã làm được rất nhiều thứ mà không cần phải viết quá nhiều code!

Supabase thực sự là một công cụ mạnh mẽ cho các developer muốn xây dựng backend nhanh chóng mà không muốn từ bỏ sức mạnh của SQL. Kết hợp với Node.js, bạn có một giải pháp linh hoạt, dễ mở rộng cho ứng dụng của mình.

Từ đây, bạn có thể mở rộng API với các tính năng như authentication, role-based access control, và real-time updates – tất cả đều được Supabase hỗ trợ natively!

Bạn đã có kinh nghiệm sử dụng Supabase chưa? Hoặc bạn có kế hoạch áp dụng stack này vào dự án nào không? Hãy chia sẻ với tôi trong phần bình luận nhé!

Cảm ơn bạn đã dành thời gian đọc bài viết. Hẹn gặp lại bạn trong các bài viết tiếp theo.

Tôi là SiuCode – Vừa code vừa siuuuu🚀

 

You may also like

Mục lục