Giới thiệu thư viện hono.dev - Tạo máy chủ API dễ dàng trên serverless

Giới thiệu thư viện hono.dev - Tạo máy chủ API dễ dàng trên serverless

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Hẳn là nhiều người ở đây đã nghe đến kiểu tấn công bảo mật Clickjacking rồi nhỉ. Kẻ tấn công thường nhúng một website (thường là mục tiêu) vào trong một iframe trên website của chúng, sau đó làm mờ hoặc ẩn nó đi rồi đặt vào vị trí các nút bấm trên web, ví dụ "Bấm vào để nhận quà". Đâu ai ngờ rằng phía trên nút bấm đó là một nút bấm khác trong iframe. Khá nguy hiểm!

    Nhưng trình duyệt đã có cách ngăn chặn kiểu tấn công này bằng các quy tắc như tiêu đề X-Frame-Options, frame-ancestors của CSP và SameSite: Lax/Strict của Cookies...

    Mới đây, đã xuất hiện thêm kiểu tấn công mới - "DoubleClickjacking" 😨. Đại ý là "hắn" lợi dụng hành động double click để lừa người dùng bấm vào một nút mà hắn muốn. Chi tiết hơn trong bài viết này: DoubleClickjacking: A New Era of UI Redressing.

    » Xem thêm
  • Mọi người đã nghe nói đến Jujutsu - jj - một dạng quản lý phiên bản cho mã nguồn (version control system) chưa? Có vẻ như nó đang nhận được nhiều sự quan tâm.

    Chờ xíu! Chẳng phải git đã quá tốt rồi sao? Thế thì chế ra thằng jj để làm gì nữa? Cũng hơi khó trả lời nhỉ? Mỗi công cụ sinh ra chắc chắn phải cải thiện hoặc khắc phục được nhược điểm của cái trước. Cho nên jj ắt hẳn phải làm được điều gì đó mà git chưa làm được nên mới nổi lên như vậy.

    Thật ra mình đã nghe nói đến jj từ vài tháng trước rồi, nhưng vào đọc thì toàn kiến thức cao siêu. Hoặc là đang mang nặng cái lối suy nghĩ của git vào trong đầu rồi nên chưa lĩnh hội ra được điều gì cả.

    Mình hay có kiểu cái gì đọc lần 1 mà không hiểu thì đọc tiếp lần 2, lần 2 không hiểu thì đọc tiếp lần 3... đến lần thứ n mà vẫn không hiểu thì bỏ. Cơ mà không phải là từ bỏ mà một thời gian sau đó quay lại đọc tiếp. Đến một lúc nào đó khả năng mình sẽ hiểu ra một ít vấn đề, thế mới tài 😆.

    Thì cái jj này có vẻ như nó đang mở ra được tính linh hoạt trong việc "cam kết" mã. Tưởng tượng bạn đang làm việc trên một dự án, đang ở nhánh này, muốn sang nhánh khác để sửa, nhưng mà lại đang viết dở ở nhánh này, thế là phải stash, rồi checkout, rồi commit, rồi merge hoặc rebase lại vào nhánh cũ... nhìn chung quá trình làm việc với git nghiêm ngặt đến mức cứng nhắc, cần nhiều thao tác để giải quyết một vấn đề, chưa kể cái cây commit (commit-tree) nữa thì ôi thôi, khỏi xem cho đỡ nhức mắt. Thế nên ông jj này đang làm cách nào đó để bạn khỏi cần phải quan tâm đến các nhánh luôn, sửa trực tiếp vào commit. Nghe ảo nhỉ 😂.

    Đấy mới lĩnh hội được đến đấy, hy vọng sau n lần đọc lại nữa mình sẽ viết được một bài chi tiết hơn về công cụ này.

    » Xem thêm
  • Gòi gòi tới công chiện gòi 🤤🤤🤤

    » Xem thêm

Vấn đề

Express.js chắc hẳn là một thư viện mà bất kỳ lập trình viên JavaScript/Node.js đều biết. Nó giúp chúng ta xây dựng một máy chủ API theo tiêu chuẩn REST một cách nhanh chóng. Bên cạnh đó là rất nhiều thư viện hay middleware được tạo ra để tương thích và dễ dàng tích hợp vào trong các dự án sử dụng express.js, làm cho nó ngày càng trở nên phổ biến, cũng như được nhiều người biết đến.

Bắt đầu với express.js cũng không hề khó. Chỉ cần qua vài bước cài đặt thư viện và viết một ít mã, rồi sử dụng lệnh node để khởi động máy chủ. Quá trình deploy cũng không khó khăn hơn là mấy. Đẩy mã lên git, từ máy chủ "pull" về, sử dụng một công cụ quản lý tiến trình như pm2 khởi động lên thế là xong.

Đấy là một quy trình gần như là điều hiển nhiên để áp dụng trong trường hợp viết và triển khai một máy chủ Node. Kể cả sau này đi làm việc ở nhiều công ty, cái công đoạn "push" mã lên git, "pull" về máy chủ rồi "pm2 restart" mà tôi gọi vui là quy trình 3P để vận hành máy chủ.

Cho đến một ngày, bất chợt anh CTO nhắc đến Cloudflare Workers, một dạng của serverless. Nào là nó làm được cái này, làm được cái kia... mỗi ngày một ít và khiến tôi trở nên tò mò. Thi thoảng mỗi khi anh nhắc lại lên mạng đọc nhưng thú thật nó thật là khó hiểu. Mặc dù ai cũng biết khái niệm về serverless nhưng tính ứng dụng của nó trong thực tế là như thế nào thì lại không biết.

Cái gì được nhắc đến nhiều lần thì cũng gây được sự chú ý. Tôi bắt đầu đọc các bài viết về serverless một cách nghiêm túc hơn, nhưng cũng chỉ là đọc trên cơ sở lý thuyết. Còn không biết cách để triển khai mã lên cái gọi là serverless thì phải làm như thế nào. Bởi vì serverless là không có máy chủ, vậy thì push - pull - pm2 restart lúc này được thực hiện ở đâu?

À hoá ra có hẳn một quy trình riêng dành cho việc deploy mọi thứ lên serverless. Thậm chí quá trình này còn đơn giản hơn nhiều so với cách 3P truyền thống. Tất cả những chỉ cần làm chỉ là chạy một lệnh deploy ở dưới máy của mình. Khi đó tất cả mã nguồn sẽ được tải lên máy chủ serverless và sẵn sàng để được chạy ngay lập tức.

Trong phạm vi bài viết này, tôi sẽ tạm thời không đề cập đến quá trình triển khai mã lên máy chủ serverless. Mà trước tiên cần phải biết đến một thư viện giúp chúng ta xây dựng API trên serverless. Tại sao ư? Tại vì express.js và các thư viện tương tự khác không thể chạy được trên nhiều máy chủ serverless.

hono.dev

hono.dev là một thư viện tương tự express.js, nó cung cấp giải pháp để xây dựng API. Nhưng tại sao lại cần hono? Thì hãy nhìn vào hướng dẫn tạo một endpoint đơn giản dưới đây của Cloudflare Workers:

export default {  
  async fetch(request, env, ctx) {  
    return new Response("Hello World!");  
  },  
};  

Đoạn mã này sẽ phản hồi lại cụm từ "Hello World!". Nếu muốn thêm một method POST thì cần phải kiểm tra thêm điều kiện:


export default {  
  async fetch(request, env, ctx) {  
    if (request.method === "GET") {  
      return new Response("Hello World!");  
    } else if (request.method === "POST") {  
      const data = await request.json();  
      return new Response(`Hello, ${data.name}!`);  
    }  
  },  
};  

Quá rườm rà và phức tạp, một máy chủ API không đơn giản chỉ như thế, mà nó còn là tập hợp của hàng chục, hàng trăm endpoint khác nhau. Đây là lúc hono phát huy tác dụng.

import { Hono } from 'hono'  
const app = new Hono()  

app.get('/', (c) => c.text('Hello World!'))  
app.post('/', (c) => c.text(`Hello ${(await c.req.body()).name}`))  

export default app  

Thật nhanh gọn phải không!

Hono.dev khá giống với express.js hoặc koa.js. Hono tập trung vào sự đơn giản, router và cả middleware. Sử dụng hono khá tương đồng với các thư viện REST API mà bạn đang sử dụng lâu nay.

Ví dụ một middleware đơn giản để đo thời gian xử lý của request:

app.use(async (c, next) => {  
  const start = Date.now()  
  await next()  
  const end = Date.now()  
  c.res.headers.set('X-Response-Time', `${end - start}`)  
});  

Hono rất nhẹ, chỉ 14kb cho gói hono/tiny khiến nó lý tưởng cho môi trường có nhiều hạn chế như serverless. Với cách triển khai ứng dụng trên máy chủ thông thường, kích thước gói hoặc kích thước thư viện không thành vấn đề vì tài nguyên hệ thống dồi dào, dễ nâng cấp. Nhưng trong môi trường serverless thì không được như thế, tài nguyên hạn hẹp nên việc tìm kiếm các thư viện nhanh và nhẹ là điều hết sức cần thiết.

Có thể bạn đã nghe đến cụm từ universal module và adapter, chúng thường được dùng để chỉ một modules có thể hoạt động trong nhiều môi trường khác nhau. Từ máy chủ, trình duyệt hay thậm chí là trong cả môi trường serverless. Để làm được điều đó, universal module tận dụng những API mà môi trường hỗ trợ để thích nghi, hoặc tạo ra các adapter để chúng ta chủ động lựa chọn. Thậm chí nếu cấu trúc dự án đủ tốt thì không cần phải sửa quá nhiều mã để chạy trong các môi trường khác nhau.

Hono hỗ trợ nhiều adapter và điều đó làm cho nó hoàn hảo trong môi trường serverless. Một vài cái tên nổi bật có thể kể đến như là Cloudflare Workers, Vercel, Netlify, AWS Lambda... hay thậm chí là cả Service Worker ở trong trình duyệt.

Ví dụ một đoạn mã chạy tốt trong môi trường Cloudflare Worker dưới đây:

import { Hono } from 'hono'  
const app = new Hono()  

app.get('/', (c) => {  
  return c.text('Hello Hono!') 
})  

export default app  

Thì để chuyển sang môi trường serverless của Netlify thì cần thay đổi Adatper:

import { Hono } from 'jsr:@hono/hono'  
import { handle } from 'jsr:@hono/hono/netlify'  

const app = new Hono()  
app.get('/', (c) => {  
  return c.text('Hello Hono!')  
})

export default handle(app)  

Lưu ý vì môi trường serverless có cách triển khai khác nhau cho nên cách tốt nhất để lựa chọn được cách cấu hình phù hợp với từng môi trường là tham khảo tài liệu của Hono.

Tài liệu của Hono cũng hết sức đơn giản và ngắn gọn, chỉ cần đọc vài lượt là có thể bắt đầu dựng ngay một dự án. Các Middleware "cây nhà lá vườn" liên tục được bổ sung để làm tăng thêm trải nghiệm cho các nhà phát triển, không cần phải phát minh lại bánh xe nữa. Ngoài ra, Hono cũng đang nhận được sự quan tâm của cộng đồng khi có tốc độ tăng trưởng trên Github rất ấn tượng.

Đây là một bài viết ngắn giới thiệu về Hono và cả những gì nó làm được. Trong bài viết sau, chúng ta sẽ cùng nhau triển khai từ đầu đến cuối một máy chủ API lên Cloudflare Workers nhé!

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...
Bấm hoặc cuộn mạnh để sang bài mới