Đăng nhập

BÀI 16: GỌI API NỘI BỘ TỪ SERVER NUXT

Cùng tiếp tục với Bài 16 – Gọi API nội bộ từ server Nuxt (Server API Route). Đây là bước quan trọng để bạn tạo backend riêng trong Nuxt, thay vì gọi API bên ngoài như reqres.in. Rất phù hợp khi bạn muốn mock dữ liệu, tạo route xử lý form, gọi database, hoặc ẩn logic phía server.


1. Server API là gì?

Nuxt cho phép bạn tạo API route nội bộ nằm trong thư mục server/api/. Bạn có thể:

  • Xử lý request POST, GET, PUT…
  • Trả JSON hoặc status code tùy ý
  • Gọi từ client bằng $fetch('/api/abc')

2. Tạo API nội bộ đầu tiên

Tạo file: server/api/hello.ts

export default defineEventHandler(() => {
  return { message: 'Xin chào từ server API' }
})

Truy cập tại đường dẫn: http://localhost:3000/api/hello


3. Gọi API nội bộ từ component

Trong bất kỳ component Vue nào:

<script setup>
const { data } = await useFetch('/api/hello')
</script>

<template>
  <div>
    {{ data.message }}
  </div>
</template>

4. Xử lý POST request (giả lập login)

Tạo file: server/api/login.ts

export default defineEventHandler(async (event) => {
  const body = await readBody(event)

  // Giả lập kiểm tra
  if (body.email === 'admin@example.com' && body.password === '123456') {
    return {
      token: 'mock-token-abc',
      user: {
        name: 'Admin',
        email: body.email
      }
    }
  }

  return createError({
    statusCode: 401,
    statusMessage: 'Tài khoản hoặc mật khẩu không đúng'
  })
})

5. Gọi API /api/login từ form

Tạo form ở pages/login.vue:

<script setup>
const email = ref('')
const password = ref('')
const error = ref('')
const router = useRouter()

async function handleLogin() {
  try {
    const res = await $fetch('/api/login', {
      method: 'POST',
      body: {
        email: email.value,
        password: password.value
      }
    })

    // Lưu token và user vào cookie
    useCookie('auth_token').value = res.token
    useCookie('user').value = res.user

    router.push('/admin')
  } catch (err) {
    error.value = err.statusMessage
  }
}
</script>

<template>
  <form @submit.prevent="handleLogin">
    <input v-model="email" placeholder="Email" />
    <input v-model="password" type="password" placeholder="Mật khẩu" />
    <button>Đăng nhập</button>
    <p style="color:red">{{ error }}</p>
  </form>
</template>

6. Ưu điểm của API nội bộ

  • Bảo mật hơn khi xử lý logic phía server
  • Tự mock dữ liệu dễ dàng khi chưa có backend
  • Dễ chuyển thành thật khi kết nối database sau này
  • Giữ logic backend + frontend trong cùng một project

7. Phân biệt $fetch()useFetch()

HàmDùng ở đâuĐặc điểm
useFetchsetupTích hợp Nuxt SSR, cache, tự reactive
$fetchtrong async, methodsDễ kiểm soát, giống axios

Bạn đã học được

  • Tạo route API nội bộ trong server/api/
  • Gọi API nội bộ bằng $fetch()useFetch()
  • Xử lý POST request với readBody()
  • Kết hợp với form đăng nhập
  • Lưu thông tin user sau khi gọi API thành công

Bài tập mở rộng

  1. Tạo API /api/register xử lý đăng ký user
  2. Form đăng ký gọi đến API này và hiển thị thông báo
  3. Tạo API /api/user trả thông tin user đang login từ cookie
  4. Tạo API /api/logout xóa token và user khỏi cookie (nâng cao)

Thảo luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.