Mở đầu — vì sao bài này quan trọng
Suốt cả khóa học này, chúng ta đã "sống" trong Postman: collection, environment, script pm.*, Newman, monitor... Postman là một cỗ máy mạnh mẽ, nhưng đôi khi nó giống như bạn mở nguyên cả một chiếc máy xúc chỉ để đào một cái hố nhỏ trồng cây. Có những tình huống mà bạn chỉ muốn gõ nhanh một request GET, xem response, rồi đóng lại — không cần tạo collection, không cần đăng nhập tài khoản, không cần đồng bộ cloud.
Đó chính là lúc REST Client trong VSCode tỏa sáng. Đây là một extension nhẹ (humao.rest-client) cho phép bạn định nghĩa HTTP request bằng một file văn bản thuần .http (hoặc .rest), rồi bấm gửi ngay trong editor. Không có UI phức tạp, không có tài khoản, không có tiến trình nền ngốn RAM.
Vì sao một QA/tester chuyên về API lại cần biết công cụ này, trong khi đã thành thạo Postman? Ba lý do rất thực tế:
- Request-as-code: File
.httplà plain text, nằm ngay trong repo, được Git quản lý version như mọi file code khác. Reviewer đọc diff của request dễ như đọc code — điều mà file.postman_collection.json(JSON dày đặc, khó đọc) không làm được. - Tốc độ khởi động: Mở VSCode (thứ bạn vốn đã mở sẵn để đọc source), gõ vài dòng, bấm Send. Không context-switch sang app khác.
- Đây là một "lightweight alternative" — một lựa chọn thay thế nhẹ, đúng như tiêu đề bài. Hiểu rõ giới hạn của nó giúp bạn chọn đúng công cụ cho đúng việc, thay vì cực đoan "chỉ Postman" hoặc "chỉ REST Client".
Khái niệm cốt lõi
File .http — đơn vị làm việc
Trái tim của REST Client là file có đuôi .http hoặc .rest. Mỗi file chứa một hoặc nhiều request, viết bằng cú pháp gần như giống hệt raw HTTP request thật:
GET https://api.vietnamcos.dev/v1/products
Accept: application/json
Đặt con trỏ vào bất kỳ dòng nào của request, bạn sẽ thấy một dòng chữ mờ "Send Request" hiện ngay phía trên. Bấm vào đó (hoặc Ctrl+Alt+R / Cmd+Alt+R trên Mac), response sẽ mở ra ở một pane bên cạnh, kèm status code, thời gian, kích thước, header và body được tô màu cú pháp.
Dấu ### — ngăn cách nhiều request
Một file .http thường chứa nhiều request. Bạn ngăn cách chúng bằng ba dấu thăng ###. Phần chữ sau ### được coi như tên/ghi chú của request:
Lấy danh sách sản phẩm
GET {{baseUrl}}/productsLấy chi tiết một sản phẩm
GET {{baseUrl}}/products/42Tạo sản phẩm mới
POST {{baseUrl}}/products
Content-Type: application/json{
"name": "Áo dài truyền thống",
"price": 850000
}
Lưu ý cực kỳ quan trọng về cú pháp body: sau dòng header cuối cùng, bạn phải để một dòng trống rồi mới đến body JSON. Đây là lỗi số một của người mới — quên dòng trống thì body không được gửi đi.
Biến với {{...}} và block @name = value
Bạn thấy {{baseUrl}} ở trên chứ? REST Client hỗ trợ biến để tránh lặp lại. Có hai cách chính:
Biến file (file variables) — khai báo trực tiếp trong file bằng cú pháp @ten = giá_trị:
@baseUrl = https://api.vietnamcos.dev/v1
@token = eyJhbGciOi... Dùng biến
GET {{baseUrl}}/orders
Authorization: Bearer {{token}}
Biến môi trường (environment variables) — khai báo trong settings.json của VSCode, dưới key rest-client.environmentVariables, cho phép bạn chuyển đổi giữa dev, staging, production bằng cách bấm vào ô góc phải dưới thanh status của VSCode. Ví dụ cấu hình:
"rest-client.environmentVariables": {
"dev": {
"baseUrl": "http://localhost:3000/v1",
"apiKey": "dev-key-123"
},
"production": {
"baseUrl": "https://api.vietnamcos.com/v1",
"apiKey": "prod-key-xyz"
}
}
Request variables — nối chuỗi request thủ công
Điểm mạnh bất ngờ của REST Client là khả năng tham chiếu response của request trước vào request sau. Bạn đặt tên request bằng comment # @name login, rồi trích xuất giá trị từ response của nó:
@name login
POST {{baseUrl}}/auth/login
Content-Type: application/json{ "email": "qa@vietnamcos.dev", "password": "secret" }
Dùng token vừa nhận được
GET {{baseUrl}}/me
Authorization: Bearer {{login.response.body.$.accessToken}}
Cú pháp {{login.response.body.$.accessToken}} nghĩa là: lấy request tên login, vào response, body, dùng JSONPath $.accessToken. Đây là cách làm chained request "cây nhà lá vườn" — đủ dùng cho debug nhanh, dù không mạnh bằng workflow script của Postman.
Những thứ REST Client KHÔNG có
Để chọn công cụ đúng, phải biết ranh giới. REST Client không có: assertion/test tự động (không có pm.test), không có test runner để chạy hàng loạt và báo pass/fail, không có reporter HTML/JUnit, không chạy được trên CI như một bộ test suite chính thức. Nó là công cụ để gửi và xem, không phải để kiểm thử tự động và báo cáo.
Tình huống thực tế
Tình huống 1 — Tiki Team và cái repo backend "biết nói"
Một nhóm backend 6 người tại một công ty thương mại điện tử (tạm gọi giống mô hình Tiki) làm API đơn hàng. Trước đây, mỗi khi có endpoint mới, developer nhắn Slack cho QA: "Ê, thử POST /orders giúp anh, payload gửi qua đây nhé" rồi dán một cục JSON. QA phải copy vào Postman, tự đoán header, tự đoán base URL.
Team quyết định thêm một thư mục docs/http/ trong repo backend, chứa các file như orders.http, payments.http. Mỗi khi developer viết xong endpoint, họ viết luôn 2-3 request mẫu vào file .http và commit chung với code. QA git pull là có ngay request chạy được, chỉ cần đổi environment sang dev.
Kết quả sau một sprint: thời gian QA "dựng" một request để thử giảm từ khoảng 5-7 phút (mò mẫm trong Postman) xuống dưới 30 giây. Quan trọng hơn, khi developer sửa endpoint (đổi tên field từ orderId sang order_id), diff trong file .http hiện rõ trong Pull Request, reviewer thấy ngay và nhắc cập nhật.
Bài học: REST Client biến request thành tài liệu sống nằm cạnh code. Nó không thay bộ test regression của bạn, nhưng nó là "smoke test bằng tay" và tài liệu API rẻ nhất bạn có thể có.
Tình huống 2 — Bạn Minh và cú debug lúc 11 giờ đêm
Minh là fresher QA tại một startup fintech ở Sài Gòn. Một tối, production báo lỗi: endpoint /wallet/balance thỉnh thoảng trả về 500. Minh cần thử đi thử lại request đó với nhiều userId khác nhau, nhanh, và ghi lại kết quả để gửi cho lead.
Nếu dùng Postman, Minh phải tạo collection tạm, tạo environment, gõ biến — mất thời gian cho một việc dùng-một-lần. Thay vào đó Minh tạo file debug-500.http:
@base = https://api.startup.vn/v1
@token = {{$dotenv TOKEN}}user bình thường
GET {{base}}/wallet/balance?userId=1001
Authorization: Bearer {{token}}user nghi ngờ gây lỗi
GET {{base}}/wallet/balance?userId=9999
Authorization: Bearer {{token}}
Minh bấm Send từng cái, thấy userId=9999 luôn 500. Response pane hiện nguyên stack trace. Minh chụp màn hình cả request lẫn response (nằm cạnh nhau, rất gọn), dán vào ticket. Lead nhìn phát hiểu ngay: user 9999 có wallet null trong DB. File .http này Minh commit vào một nhánh debug/ để lần sau ai gặp lại còn có mẫu.
Bài học: Với debug ad-hoc, dùng-một-lần, REST Client nhanh hơn Postman vì độ ma sát gần bằng không. Cú pháp {{$dotenv TOKEN}} còn cho phép đọc token từ file .env để không lộ secret trong file commit.
Tình huống 3 — Onboarding nhân viên mới ở agency
Một agency phần mềm ở Đà Nẵng thường xuyên nhận dev/QA mới. Trước đây họ export file Postman collection .json gửi qua email, nhưng file 4000 dòng JSON khó ai đọc để hiểu API, và mỗi lần cập nhật lại phải export-import thủ công, dễ lệch phiên bản.
Họ chuyển sang duy trì một file api-tour.http trong repo mẫu (starter repo). File này chứa khoảng 20 request được sắp thứ tự như một "tour": đăng ký → đăng nhập → tạo tài nguyên → sửa → xóa, mỗi request có comment ### giải thích bằng tiếng Việt. Nhân viên mới clone repo, mở file, đọc từ trên xuống là hiểu luồng nghiệp vụ, và bấm Send để chạy thử ngay.
Bài học: File .http vừa là công cụ thử, vừa là tài liệu dạng runnable (chạy được). Với nhu cầu onboarding/demo, nó dễ đọc và dễ maintain hơn hẳn một file JSON export.
Hướng dẫn từng bước
Bước 1 — Cài extension. Mở VSCode, vào tab Extensions (Ctrl+Shift+X), gõ "REST Client", chọn extension của tác giả Huachao Mao (id: humao.rest-client), bấm Install. Không cần restart, không cần đăng nhập.
Bước 2 — Tạo file .http đầu tiên. Tạo file smoke.http trong project. Gõ request đơn giản nhất để kiểm tra:
GET https://jsonplaceholder.typicode.com/todos/1
Đặt con trỏ vào dòng đó, bấm chữ "Send Request" vừa hiện ra. Response mở ở pane bên phải — bạn vừa gửi request đầu tiên.
Bước 3 — Thêm nhiều request và ngăn cách. Dùng ### để tách:
Todo số 1
GET https://jsonplaceholder.typicode.com/todos/1Tạo post mới
POST https://jsonplaceholder.typicode.com/posts
Content-Type: application/json{
"title": "Bài kiểm thử",
"body": "Nội dung",
"userId": 1
}
Nhớ dòng trống giữa header và body JSON.
Bước 4 — Rút gọn bằng biến file. Thêm khai báo @ ở đầu file:
@host = https://jsonplaceholder.typicode.comDùng biến
GET {{host}}/users/1
Bước 5 — Cấu hình environment cho nhiều tầng. Mở settings.json (Command Palette → "Preferences: Open User Settings (JSON)"), thêm block rest-client.environmentVariables như đã trình bày ở phần khái niệm. Sau đó, ở góc phải dưới thanh status VSCode sẽ có chữ chỉ environment hiện tại — bấm vào để đổi giữa dev/production.
Bước 6 — Chained request. Đặt # @name cho request tạo token, rồi tham chiếu {{tênRequest.response.body.$.field}} ở request sau. Chạy request login trước, rồi mới chạy request phụ thuộc — REST Client lưu response gần nhất để nối.
Bước 7 — Bảo mật secret. Tạo file .env cùng thư mục, đặt TOKEN=abc123, rồi dùng {{$dotenv TOKEN}} trong file .http. Thêm .env vào .gitignore. Như vậy file .http commit lên repo mà không lộ token.
Bước 8 — Chia sẻ và review. Commit file .http vào repo. Trong Pull Request, reviewer đọc trực tiếp request như đọc code. Đây là toàn bộ vòng đời làm việc gọn nhẹ mà bạn hướng tới.
Lỗi thường gặp & mẹo
Quên dòng trống trước body. Đây là lỗi phổ biến nhất. Nếu POST của bạn gửi đi mà server báo body rỗng, gần như chắc chắn bạn thiếu dòng trống giữa dòng header cuối và JSON. Header — [dòng trống] — body, luôn luôn.
Nhầm biến file @name = value với biến trong request. Khai báo dùng dấu @ (không có ngoặc nhọn), còn khi dùng thì bọc {{name}}. Viết @base = ... để định nghĩa, viết {{base}} để gọi.
Tưởng REST Client chạy được assertion. Không. Nếu bạn cần expect(status).to.equal(200) chạy tự động và báo pass/fail, đó là việc của Postman/Newman hay code-based test — không phải REST Client. Đừng ép công cụ nhẹ làm việc nặng; hãy dùng nó đúng vai trò "gửi và xem bằng mắt".
Lộ secret trong file commit. Đừng bao giờ gõ thẳng token/API key vào file .http rồi commit. Dùng {{$dotenv KEY}} đọc từ .env, hoặc đặt vào environment variables trong settings.json cá nhân (không commit).
Mẹo — biến động dựng sẵn. REST Client có sẵn {{$guid}}, {{$timestamp}}, {{$randomInt 1 100}}, {{$datetime iso8601}}. Rất tiện để tạo dữ liệu duy nhất, ví dụ email test: qa+{{$timestamp}}@vietnamcos.dev.
Mẹo — copy as curl. Chuột phải trong response hoặc dùng Command Palette, REST Client cho phép "Copy Request As cURL" — hữu ích khi bạn cần dán lệnh vào terminal hoặc gửi cho người khác.
Mẹo — xem lịch sử. Command Palette → "Rest Client: Request History" cho phép xem lại các request đã gửi, kể cả khi bạn không lưu vào file.
Mẹo — gửi form và file. Với Content-Type: application/x-www-form-urlencoded, body viết dạng key=value&key2=value2. Với upload file, dùng multipart/form-data kèm cú pháp < ./đường-dẫn-file để nạp nội dung từ đĩa.
Bài tập thực hành
- Dựng file
.httpcơ bản. Cài extensionhumao.rest-client. Tạo fileluyen-tap.httpvới 3 request tớihttps://jsonplaceholder.typicode.com: mộtGET /posts/1, mộtGET /posts?userId=1, mộtPOST /postscó body JSON. Ngăn cách bằng###và đặt tên tiếng Việt cho từng request. Đảm bảoPOSTchạy đúng (chú ý dòng trống).
- Biến hóa với environment. Khai báo
@hostbằng biến file, sau đó chuyển sang cấu hìnhrest-client.environmentVariablestrongsettings.jsonvới hai môi trườngdevvàproduction(trỏ tới hai base URL khác nhau). Chuyển qua lại và quan sát request thay đổi.
- Chained request. Với một API có đăng nhập (dùng API công khai bất kỳ hoặc mock local từ Bài 19), tạo request
# @name login, lấy token từ response bằng{{login.response.body.$.token}}, rồi dùng nó ở một request được bảo vệ. Ghi lại: điều này khác gì so với cách chain trong Postman?
- Bảo mật. Tạo file
.envchứa mộtTOKEN, dùng{{$dotenv TOKEN}}trong file.http, thêm.envvào.gitignore. Viết 3 dòng nhận xét: khi nào bạn sẽ chọn REST Client thay vì Postman, và khi nào thì ngược lại.
Tóm tắt
REST Client (humao.rest-client) là một lựa chọn thay thế nhẹ cho Postman, sống ngay trong VSCode. Bạn định nghĩa request bằng file văn bản .http/.rest với cú pháp gần giống raw HTTP: dòng method + URL, các header, một dòng trống, rồi body. Nhiều request ngăn cách bằng ###. Bạn rút gọn bằng biến file @name = value (gọi qua {{name}}), chuyển tầng dev/staging/production qua rest-client.environmentVariables trong settings.json, và nối request thủ công bằng # @name cùng cú pháp {{name.response.body.$.field}}.
Sức mạnh thật sự của nó là request-as-code: file plain text nằm trong Git, review dễ như review code, vừa là công cụ thử vừa là tài liệu chạy được — lý tưởng cho smoke test bằng tay, debug ad-hoc, và onboarding. Nhưng hãy nhớ giới hạn: nó không có assertion tự động, không có test runner, không có reporter, không thay được bộ test suite trên CI. Chọn công cụ đúng cho đúng việc — REST Client cho "gửi và xem nhanh", còn Postman/Newman cho "kiểm thử tự động và báo cáo" — đó mới là tư duy của một API tester trưởng thành.