Cách Viết Testcase Api / Top 11 Xem Nhiều Nhất & Mới Nhất 9/2023 # Top Trend | Ezlearning.edu.vn

How To Write Test Cases ( Hướng Dẫn Cách Viết Testcases)

Đầu tiên, chúng ta cùng tìm hiểu:

A. Testcase là gì?

Testcase là các trường hợp kiểm thử bao gồm các hành động được thực hiện nhằm kiểm tra từng chức năng của ứng dụng phần mềm có hoạt động đúng theo như mong muốn hay không.

B. Làm thế nào để có thể viết được Testcase tốt?

I. Trước khi bắt tay vào việc viết Testcase thì chúng ta cần nhớ những điểm sau đây:

Là 1 newbie, mới gia nhập công ty, chúng ta nên hỏi QA leader về template viết Testcase và xin file đó để làm. ( Vì mỗi công ty sẽ có cách viết khác nhau)

Viết Testcase nhớ phải bám sát tài liệu yêu cầu ( spec)

1 Testcase ID không quá 15 bước ( step)

Trước khi viết Testcase thì ta nên đọc và phân tích tài liệu thật kĩ càng, có chỗ nào chưa hiểu thì đặt Q&A ( Question & Answer) với các member trong team hoặc QA leader hoặc khách hàng để việc viết testcase và test được chính xác và chắc chắn hơn.

II. Những nguyên tắc để viết TestCase tốt:1. Các trường hợp kiểm thử cần phải đơn giản và minh bạch: (Test Cases need to be simple and transparent)

Tạo các testcase đơn giản nhất có thể nhưng vẫn phải rõ ràng và dễ hiểu.

2. Tạo Testcase với vai trò mình là End -user (người dùng ứng dụng đó)

Mục tiêu cuối cùng của bất kì dự án phần mềm nào cũng là đáp ứng được tất cả các yêu cầu của khách hàng. Vậy nên đặt vị trí của mình là người dùng thì sẽ thực hiện test được hiệu quả hơn. Chứ không nên có suy nghĩ mình chỉ là QA, chỉ là tester nên mình cứ test theo những gì spec nói thôi. Khi thấy UI nó khó dùng thì ta nên ta feedback lại với PM hay với mọi người để tất cả cùng cân nhắc có nên thay đổi hay không.

3. Mỗi testcase đều phải được xác định

Đặt tên ID cho từng testcase để dễ dàng theo dõi

b, Phân vùng tương đương (Equivalence Partition): Kỹ thuật này phân vùng phạm vi thành các phần / nhóm bằng nhau có xu hướng có cùng hành vi.

c,Kỹ thuật Bảng quyết định (Decision tables) : Phương pháp này tìm được những tác động khi kết hợp các yếu tốt đầu vào khác nhau và các trạng thái phần mềm mà phải thực hiện đúng các quy tắc nghiệp vụ khác.

d, Kỹ thuật đoán lỗi (Error Guessing Technique): Đây là đoán / dự đoán lỗi có thể phát sinh trong khi thực hiện test manual.

5. Review chéo (Peer Review): Sau khi tạo xong Testcase, hãy nhờ đồng nghiệp của bạn review giúp, có thể là QA leader hay QA cùng team để phát hiện ra các case mà bạn còn thiếu hoặc bạn chưa nghĩ tới.

C. Thực hành viết Testcase:

Khi join vào dự án, chúng ta được QA Leader giao cho nhiệm vụ là viết Testcase cho màn Login của 1 website với UI như thế này:

Ta sẽ viết theo format chuẩn như sau:

Testcase ID Test Scenario Test Steps Test Data Expected Results Actual Results Status

LG01

Check UI

As expected

Pass

LG02

Check button Sign in when user input valid data

4. User can login successfully and system go to the Homepage

As expected

Pass

LG03

Check button Sign in when user input invalid data

4. User cannot login and system shows error message: Email is invalid.

As expected

Pass

Qua 3 ví dụ trên các bạn có thể dễ dàng hơn với việc với Testcase rồi đúng không nào? Tương tự các case trên, các bạn áp dụng Kĩ thuật Bảng quyết định, ta sẽ có thêm các case sau:

Cách Viết Rails Api Document

Như các bạn đã biết, 1 ứng dụng API sẽ không có giao diện cho người dùng trên trình duyệt, thay vào đó sẽ là các dữ liệu kiểu JSON hoặc XML … được hiển thị mà thôi. Do đó, khi viết 1 ứng dụng API đòi hỏi người viết phải viết Documents (Tài liệu) kèm theo để hỗ trợ cho những Developers sử dụng chúng và đặc biệt là QA, những người sẽ gặp nhiều khó khăn hơn trong việc hiểu được tác dụng của các API.

Có nhiều cách để viết Documents, đơn giản nhất sẽ là viết bằng tay ra file Excel hoặc Word chẳng hạn. Chỉ rõ API này mục đích làm gì, URL để truy cập đến như thế nào, dữ liệu gửi Request là gì, Dữ liệu Response trả về là gì … Xong rồi thì gửi chúng cho bên Developers/QA có như cầu sử dụng để họ đọc. Cách này khá thủ công và tốn nhiều efforts trong khi giá trị mang lại cho những người sử dụng chúng lại chưa chắc đã cao, vì đơn giản chúng không có 1 Format thống nhất và rất dễ thiếu thông tin.

Hôm nay mình sẽ giới thiệu cho các bạn 1 Tool khá nổi tiếng trong việc viết API docs, đó là Swagger (UI). Cụ thể Swagger là gì thì các bạn có thể search để tìm hiểu, Swagger nên ở phạm vi bài viết này mình xin phép không giới thiệu lại, thay vào đó sẽ mình sẽ đi sâu vào cách triển khai Swagger theo cách “Khoa học” và “Developer” nhất có thể.

Quay lại 1 chút thì các bài viết trước đây khi hướng dẫn triển khai Swagger UI thường tiếp cận theo hướng copy UI của Swagger rồi “ném” vào Project của mình (clone lại Repository Swagger hoặc copy file CSS, JavaScript của Swagger) không thì viết sẵn 1 file XML (JSON) rồi render lại chúng ra View.

Còn cách mà “Khoa học” và theo hướng “Developers” ở đây mình muốn nói đến là:

Có khả năng tái sử dụng code, viết Docs cũng như viết Code, cái gì giống nhau là gọi lại dùng được

Dễ dàng mở rộng (Scale), ví dụ: khi thêm 1 trường vào Model hay đổi tên 1 trường chẳng hạn thì file Documents cũng tự động được update chẳng hạn

Tổ chức Trees (Cây thư mục) rõ ràng và khoa học

Trong Rails thì có 2 Gem thường được dùng để Implement Swagger là: swagger-docs và swagger-blocks. Sự khác biệt lớn nhất giữa 2 Gem này là swagger-blocks được support đến v2.0 của Swagger Specification còn swagger-docs chỉ dừng lại ở v1.2, và theo thông tin trên Repo của swagger-docs thì họ chưa có kế hoạch update lên v2.0. Do đó trong Demo này mình sẽ triển khai với gem swagger-blocks.

Note: cả 2 gem kể trên đều không sinh ra giao diện UI/UX theo kiểu Swagger mà chỉ sinh ra 1 file .json phù hợp với format của Swagger UI mà thôi, do đó để có giao diện như Swagger mang lại, chúng ta cần 1 Gem nữa là swaggeruiengine.

Bắt đầu, tạo 1 ứng dụng Rails API bằng cách gõ các lệnh sau trên Terminal:

Sau đó add thêm 2 Gem mình giới thiệu phía trên vào Gemfile rồi bundle chúng:

Note: khi triển khai thực tế mình gặp phải 1 vấn đề khi call API bằng tool Postman – tool hỗ trợ test các Request API – thì Oki nhưng khi Deploy lên Server và call API qua lại giữa các Server thì bị trả về 404, sau 1 hồi search thì tìm hiểu ra là do thiếu config CORS. Để khắc phục thì bạn chỉ cần add thêm vào Gem như sau:

và config cho Rails như sau:

Trên Repo của gem Swagger-Blocks có giới thiệu khá chi tiết về cách Setup Swagger, tuy nhiên mình thấy 1 số điểm chưa thực sự “dry” code cho lắm, do đó mình sẽ custom lại Trees (cấu trúc) của Swagger trong Project của mình 1 chút để tận dụng được những cái sài chung (tái sử dụng code í mà) như kiểu các Paramerter hay được gọi đi gọi là hoặc là các Response phổ biến (lỗi 404 hay 500 chẳng hạn). Đồng thời cũng giúp chúng ta dễ dàng mở rộng code khi cần thiết trong tương lai.

Cấu trúc thư mục của Swagger khi đó sẽ như thế này:

So sánh với tài liệu trên Repo của Swagger-Blocks thì cách tổ chức của mình có 1 vài điểm mà cá nhân mình nghĩ sẽ rành mạch và rõ ràng hơn.

Theo Swagger hướng dẫn thì mỗi Documents sẽ ứng với 1 Controller, cách viết này khá dễ hiểu, nhưng các bạn có thế dễ dàng nhận ra là Controller sẽ bị phình to “cực kỳ” nhanh nếu đặt Docs trong đó. Và Controller cũng không phải là là 1 nơi lý tưởng để xử lý Docs. Do đó, chúng ta hãy tách ra thành 1 Module riêng biệt – chuyển xử lý Docs. Cụ thể ở đây mình sẽ để vào trong thư mục concern/swagger rồi sau đó Include lại vào Controller.

Sẽ có rất nhiều Parameter dùng chung, ví dụ: userID được dùng chung khi get thông tin của User cũng như update thông tin user chẳng hạn. Do đó mình tạo ra 1 file chúng tôi để chứa những thứ dùng chung, khi cần dùng thì sẽ include lại vào file Docs (ở đây là user_api.rb)

Tương tự, sẽ có rất nhiều Response Error được dùng chung, kiểu lỗi 401 – not authorize hay là 404 – not found Records do đó mình tạo ra 1 file error_response.rb để viết chung, khi cần lại include vào file chứa Docs (ở đây là user_api.rb)

Response Success 200 tuy mỗi API sẽ trả về 1 thông tin khác nhau, nhưng không phải là không có điểm chung. Chẳng hạn, các API sau đều trả về thông tin của User sau khi Request thành công đó là: API show, API edit thông tin của User và API login. Do đó, chúng ta phải tìm cách tái sử dụng Code. May thay, với Swagger chúng ta có thể sử dụng $ref để gọi tới 1 schema được định nghĩa trước đó (ở đây là: user_schema.rb trong modes/concern/swagger)

Chú ý cần tạo Router cho Documents để còn biết URL mà xem trên trình duyệt.

Sau khi tạo Router, thì chúng ta cũng tạo ra 1 controller ứng với router này và định nghĩa các thông số cơ bản của API Documents như:

Version Swagger sử dụng -Tittle, Description của API

Đường dẫn mặc định của API

Kiểu dữ liệu sinh ra của API (thường là Json hoặc có thể là XML) ….

Trong method index của api_docs_controller các bạn nhớ gọi method để render ra những thông tin API mà mình muốn viết Docs.

Đến đây là các bạn có thể bật server lên và vào URL: localhost:3000/api_docs.json để xem thanh quả rồi.

Chúng ta sẽ dùng gem swagger_ui_engine và config 1 chút để có giao diện Swagger UI cho dữ liệu json mình vừa tạo ra ở bên trên như sau:

Xong. Tới đây bạn có thể restart lại server, truy cập lại URL localhost:3000/api_docs để thấy thành quả.

Restful Api Là Gì? Cách Thiết Kế Restful Api

Có thể nói nguyên lí và cấu trúc dữ liệu RESTful được biết đến rộng rãi trong giới lập trình web nói chung và lập trình ứng dụng nói riêng.

Có thể nói bản thân REST không phải là một loại công nghệ. Nó là phương thức tạo API với nguyên lý tổ chức nhất định. Những nguyên lý này nhằm hướng dẫn lập trình viên tạo môi trường xử lý API request được toàn diện.

Để hiểu rõ hơn về RESTful API ta sẽ đi lần lượt giải thích các khái niệm API, REST hay RESTful.

RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource. Nó chú trọng vào tài nguyên hệ thống (tệp văn bản, ảnh, âm thanh, video, hoặc dữ liệu động…), bao gồm các trạng thái tài nguyên được định dạng và được truyền tải qua HTTP.

API ( Application Programming Interface) là một tập các quy tắc và cơ chế mà theo đó, một ứng dụng hay một thành phần sẽ tương tác với một ứng dụng hay thành phần khác. API có thể trả về dữ liệu mà bạn cần cho ứng dụng của mình ở những kiểu dữ liệu phổ biến như JSON hay XML.

REST ( REpresentational State T ransfer) là một dạng chuyển đổi cấu trúc dữ liệu, một kiểu kiến trúc để viết API. Nó sử dụng phương thức HTTP đơn giản để tạo cho giao tiếp giữa các máy. Vì vậy, thay vì sử dụng một URL cho việc xử lý một số thông tin người dùng, REST gửi một yêu cầu HTTP như GET, POST, DELETE, vv đến một URL để xử lý dữ liệu.

RESTful API là một tiêu chuẩn dùng trong việc thiết kế các API cho các ứng dụng web để quản lý các resource. RESTful là một trong những kiểu thiết kế API được sử dụng phổ biến ngày nay để cho các ứng dụng (web, mobile…) khác nhau giao tiếp với nhau.

Chức năng quan trọng nhất của REST là quy định cách sử dụng các HTTP method (như GET, POST, PUT, DELETE…) và cách định dạng các URL cho ứng dụng web để quản các resource. RESTful không quy định logic code ứng dụng và không giới hạn bởi ngôn ngữ lập trình ứng dụng, bất kỳ ngôn ngữ hoặc framework nào cũng có thể sử dụng để thiết kế một RESTful API.

RESTful hoạt động như thế nào?

GET (SELECT): Trả về một Resource hoặc một danh sách Resource.

POST (CREATE): Tạo mới một Resource.

PUT (UPDATE): Cập nhật thông tin cho Resource.

DELETE (DELETE): Xoá một Resource.

Những phương thức hay hoạt động này thường được gọi là CRUD tương ứng với Create, Read, Update, Delete – Tạo, Đọc, Sửa, Xóa.

Hiện tại đa số lập trình viên viết RESTful API giờ đây đều chọn JSON là format chính thức nhưng cũng có nhiều người chọn XML làm format, nói chung dùng thế nào cũng được miễn tiện và nhanh.

Authentication và dữ liệu trả về

RESTful API không sử dụng session và cookie, nó sử dụng một access_token với mỗi request. Dữ liệu trả về thường có cấu trúc như sau:

{ "data" : { "id": "1", "name": "TopDev" } } Status code

Khi chúng ta request một API nào đó thường thì sẽ có vài status code để nhận biết sau:

200 OK – Trả về thành công cho những phương thức GET, PUT, PATCH hoặc DELETE.

201 Created – Trả về khi một Resouce vừa được tạo thành công.

204 No Content – Trả về khi Resource xoá thành công.

304 Not Modified – Client có thể sử dụng dữ liệu cache.

400 Bad Request – Request không hợp lệ

401 Unauthorized – Request cần có auth.

403 Forbidden – bị từ chối không cho phép.

404 Not Found – Không tìm thấy resource từ URI

405 Method Not Allowed – Phương thức không cho phép với user hiện tại.

410 Gone – Resource không còn tồn tại, Version cũ đã không còn hỗ trợ.

415 Unsupported Media Type – Không hỗ trợ kiểu Resource này.

422 Unprocessable Entity – Dữ liệu không được xác thực

429 Too Many Requests – Request bị từ chối do bị giới hạn

Nên sử dụng Version

Luôn sử dụng version để khi bạn cần nâng cấp API mà vẫn hỗ trợ các API cũ.

Xây dựng API với Laravel

Lấy việc xây dựng api trên Laravel để làm ví dụ, trước khi đi vào ta tổng quan về Http Request.

HTTP Request

HTTP request có tất cả 9 loại method , 2 loại được sử dụng phổ biến nhất là GET và POST

GET: được sử dụng để lấy thông tin từ server theo URI đã cung cấp.

HEAD: giống với GET nhưng response trả về không có body, chỉ có header.

POST: gửi thông tin tới sever thông qua các biểu mẫu http.

PUT: ghi đè tất cả thông tin của đối tượng với những gì được gửi lên.

PATCH: ghi đè các thông tin được thay đổi của đối tượng.

DELETE: xóa tài nguyên trên server.

CONNECT: thiết lập một kết nối tới server theo URI.

OPTIONS: mô tả các tùy chọn giao tiếp cho resource.

TRACE: thực hiện một bài test loop – back theo đường dẫn đến resource.

RESTful Route

Viết Api thì sẽ khai báo router vào file routes/api.php thay vì sử dụng file routes/web.php. Các setting mặc cho file api.php trong laravel:

Url: những route được khai báo trong file này mặc định có prefix url là api (ví dụ: topdev.vn/api/products)

Middleware: mặc định sẽ được gán Middleware Group là api, trong file app/Http/Kernel sẽ thấy 2 middleware thuộc Middleware Group: api là throttle (giới hạn request / time) và bindings (model binding).

Có thể tùy chỉnh giá trị mặc định này trong method mapApiRoutes trong file app/Providers/RouteServiceProvider.php

Tạo các route để thực hiện các thao tác như CRUD (Create, Read, Update, Delete):

# Sử dụng put nếu update toàn bộ các field # Sử dụng patch nếu update 1 vài field

Mặc định route đã được gán middleware bindings, nếu muốn sử dụng model binding trong controller thì chúng ta sửa lại tham số trong route như sau:

Ngoài ra trong laravel cũng hỗ trợ chúng ta 1 cách khai báo ngắn gọn hơn:

Resource Controllers

Tương ứng với các Route RESTful đã khai báo ở trên, đặc biệt nếu dùng method apiResource thì laravel cũng hỗ trợ các method xử lí tương ứng trong controller.

Để tạo ra Resource Controllers chúng ta chạy lệnh sau

php artisan make:controller Api/ProductController -api File ProductController tạo ra sẽ như sau<?php namespace AppHttpControllersApi; use IlluminateHttpRequest; use AppHttpControllersController; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpResponse */ public function show($id) { } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param int $id * @return IlluminateHttpResponse */ public function update(Request $request, $id) { } /** * Remove the specified resource from storage. * * @param int $id * @return IlluminateHttpResponse */ public function destroy($id) { } }

Ngoài ra nếu muốn sử dụng model binding khi tạo Resource Controllers thì dùng lệnh bên dưới

php artisan make:controller Api/ProductController --api --model=Models/Product

File ProductController tạo ra sẽ như sau, chúng ta để ý tham số của các method show, update, destroy sẽ thay đổi 1 chút.

<?php namespace AppHttpControllersApi; use AppModelsProduct; use IlluminateHttpRequest; use AppHttpControllersController; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { } /** * Display the specified resource. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function show(Product $product) { } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function update(Request $request, Product $product) { } /** * Remove the specified resource from storage. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function destroy(Product $product) { } }

Demo 1 đoạn code đơn giản trong controller kết hợp với model binding và route apiResource khi xây dựng API:

<?php namespace AppHttpControllersApi; use AppHttpControllersController; use AppModelsProduct; use IlluminateHttpRequest; class ProductController extends Controller { /** * Display a listing of the resource. * */ public function index() { return Product::all(); } /** * Store a newly created resource in storage. * * @param Request $request */ public function store(Request $request) { } /** * Display the specified resource. * * @param Product $product * @return Product */ public function show(Product $product) { return $product; } /** * Update the specified resource in storage. * * @param Request $request * @param Product $product * @return bool */ public function update(Request $request, Product $product) { } /** * Remove the specified resource from storage. * * @param Product $product * @throws Exception */ public function destroy(Product $product) { } }

Mặc định khi sử dụng route apiResource thì dữ liệu trả về sẽ tự động được chuyển sang kiểu JSON và sẽ có status tương ứng nên chỉ cần return dữ liệu ra là được.

Còn nếu muốn tùy biến status trả về thì có thể tham khảo cách phía dưới có sử dụng class IlluminateHttpResponse để lấy status thay vì fix giá trị vào ví dụ như HTTP_OK tương ứng sẽ là 200

<?php namespace AppHttpControllers; use AppModelsProduct; use IlluminateHttpRequest; use IlluminateHttpResponse; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpJsonResponse */ public function index() { $products = Product::all(); } } Eloquent Resources

Khi xây dựng API, bạn có thể cần transform dữ liệu từ controller trước khi trả về cho người dùng ứng dụng của bạn, laravel cũng đã hỗ trợ điều này với Eloquent Resources

Để tạo ra 1 class chuyển đổi chúng ta chạy lệnh sau

php artisan make:resource Product

File app/Http/Resources/Product.php sẽ có nội dung như sau

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class Product extends JsonResource { /** * Transform the resource into an array. * * @param IlluminateHttpRequest $request * @return array */ public function toArray($request) { return parent::toArray($request); } }

Mình sẽ tùy chỉnh dữ liệu trả về là chỉ có title và price

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class Product extends JsonResource{ /** * Transform the resource into an array. * * @param IlluminateHttpRequest $request * @return array */ public function toArray($request){ return [ ]; } }

Ở controller thì mình sẽ sửa lại như sau

<?php namespace AppHttpControllersApi; use AppHttpControllersController; use AppModelsProduct; use IlluminateHttpRequest; use AppHttpResourcesProduct as ProductResource; class ProductController extends Controller{ /** * Display a listing of the resource. * */ public function index(){ $products = Product::all(); return ProductResource::collection($products); } /** * Store a newly created resource in storage. * * @param Request $request */ public function store(Request $request){ return new ProductResource($product); } /** * Display the specified resource. * * @param Product $product * @return Product */ public function show(Product $product){ return new ProductResource($product); } /** * Update the specified resource in storage. * * @param Request $request * @param Product $product * @return bool */ public function update(Request $request, Product $product){ } /** * Remove the specified resource from storage. * * @param Product $product * @throws Exception */ public function destroy(Product $product){ } } Authorization

Hiện tại có 3 cơ chế Authorize chính:

Tùy thuộc vào service của bạn, mà hãy chọn loại Authorize có mức độ phù hợp, cố gắng giữ nó càng đơn giản càng tốt.

CORS Policy

Viết API thì cũng cần chú ý về CORS là gì?

API Document

API document là một phần tương tự như Unit Test vậy - lấy ngắn để nuôi dài.

Mô tả đầy đủ về params request: gồm những params nào, datatype, require hay optional.

Nên đưa ra các ví dụ về HTTP requests và responses với data chuẩn.

Cập nhật Docs thường xuyên, để sát nhất với API có bất cứ thay đổi gì.

Format, cú pháp cần phải nhất quán, mô tả rõ ràng, chính xác.

10 Cách Tốt Nhất Để Viết Các Rest Api Node.js

Bài viết được dịch từ: https://blog.risingstack.com/10-best-practices-for-writing-node-js-rest-apis/

Một trong những trường hợp sử dụng thông dụng nhất của chúng tôi là viết các RESTful API. Khi chúng tôi đang hỗ trợ khách hàng bằng cách tìm các vấn đề trong ứng dụng của họ với Trace (công cụ giám sát chúng tôi thì phát hiện ra rằng có rất nhiều các developer đang gặp vấn đề với REST API. Do đó, tôi mong rằng các cách chúng tôi sử dụng với RisingStack sẽ giúp được bạn:

1. Sử dụng phương thức HTTP và các API Route

Hãy tưởng tượng rằng bạn đang xây dựng một RESTful API chúng tôi để tạo, cập nhật, gọi thông tin hay xóa người dùng. Với các tính năng đó HTTP đã cung cấp một bộ đầy đủ các phương thức: và.

Cách tối ưu nhất là các API route của bạn chỉ nên sử dụng danh từ như là các định danh tài nguyên. Các route khi đó sẽ trông như thế này:

POST /user hay PUT /user:/id để tạo người dùng mới.

GET /user để lấy danh sách người dùng.

GET /user/:id để lấy thông tin của một người dùng.

PATCH /user/:id để sửa một bản ghi người dùng đã có.

DELETE /user/:id để xóa một người dùng.

Các API route của bạn chỉ nên sử dụng danh từ như là các định danh tài nguyên.

2. Sử dụng mã status HTTP đúng

Nếu có gì xảy ra khi server đang xử lý một request, bạn cần thiết lập đúng mã status trong response trả về:

2xx, nếu không có lỗi (thành công).

3xx, nếu tài nguyên đã bị gỡ bỏ.

4xx, nếu request không được thực hiện do lỗi client.

5xx, nếu có lỗi ở phía API (một ngoại lệ nào đó xảy ra,…).

Nếu bạn sử dụng Express, thiết lập mã status khá dễ dàng: res.status(500).send({error: 'Internal server error happened'}). Với Restify: res.status(201).

Bạn có thể xem danh sách đầy đủ các mã status ở đây.

3. Sử dụng các header HTTP để gửi metadata

Để đính kèm các metadata vào payload bạn sắp gửi, sử dụng HTTP header. Các header sẽ bao gồm các thông tin:

Đây là một danh sách các header HTTP đã chuẩn hóa.

Nếu bạn cần thiết lập bất cứ metadata custom nào trong header, hãy thêm tiền tố X vào phía trước. Ví dụ, nếu bạn đang sử dụng CSRF token, cách thông thường (nhưng không chuẩn) là đặt tên kiểu X-Csrf-Token. Tuy nhiên, theo RFC 6648 thì sẽ gây khó hiểu. Với các API mới không nên sử dụng các tên header dễ gây xung đột với các ứng dụng khác. Ví dụ, OpenStack sẽ tự động thêm tiền tố vào header với OpenStack:

Chú ý rằng các chuẩn HTTP không định nghĩa bất cứ giới hạn kích cỡ nào trong header. Tuy nhiên chúng tôi (kể từ lúc viết bài này) đã buộc object header nhận một giới hạn kích thước là 80kB cho lý do thực tế.

Không cho phép kích thước tổng của các HTTP header (bao gồm các mã status) vượt quá HTTP_MAX_HEADER_SIZE. Điều này giúp bảo vệ các embedder khỏi các cuộc tấn công từ-chối-dịch-vụ, khi kẻ tấn công sẽ gửi các header không-kết-thúc cho các embedder lưu giữ buffering.

4. Chọn đúng framework cho REST API Node.js

Express, Koa hay Hapi

Express, Koa hay Hapi có thể được sử dụng để tạo ra các ứng dụng nền web, chúng hỗ trợ templating và rendering. Nếu ứng dụng của bạn cần cung cấp dịch vụ phía người dùng, hãy thử dùng một trong số chúng và tận hưởng thành quả.

Restify

Ở một khía cạnh khác, Restify tập trung hoàn toàn vào việc giúp bạn xây dựng các dịch vụ REST. Restify tồn tại để giúp bạn xây dựng các dịch vụ API “chuẩn” đáng kể, dễ bảo trì. Restify cũng đi kèm với công cụ hỗ trợ tự động DTrace.

Về mức độ phủ sóng thì Restify đang được sử dụng trong rất nhiều các ứng dụng, điển hình như npm hay Netflix.

Restify tồn tại để giúp bạn xây dựng các dịch vụ API “chuẩn” đáng kể, dễ bảo trì.

@RisingStack

5. Test black-box các REST API

Một trong những cách hay nhất để test các REST API là xem chúng như các black-box.

Black-box test là phương pháp kiểm thử chức năng của ứng dụng mà không cần quan tâm đến cấu trúc bên trong của nó hay cách nó hoạt động. Do đó, sẽ không cần mock dependency nào, hệ thống sẽ được test như một thể duy nhất.

Để giúp bạn test các REST API theo phương pháp black-box này, ta sẽ sử dụng module supertest.

Có lẽ bạn sẽ thắc mắc: làm thế nào để phổ biến dữ liệu vào trong database phục vụ cho các REST API?

Thông thường, test thường được viết làm sao để chúng tạo ra càng ít các giả định cho trang thái hệ thống càng tốt. Tuy vậy, trong một vài bối cảnh bạn cần biết chính xác trạng thái của hệ thống, bạn có thể tạo các assertion và đạt được mức độ test cao hơn.

Tùy thuộc vào nhu cầu của bạn, bạn có thể phổ biến cơ sở dữ liệu với các dữ liệu test theo một trong các cách sau:

Chạy kịch bản test black-box theo một tập con đã biết của dữ liệu production.

Phổ biến database với dữ liệu thủ công trước khi chạy các test case.

Dĩ nhiên, black-box test không đồng nghĩa với việc bạn không cần viết unit test. Trong hầu hết các trường hợp, bạn vẫn cần viết unit test cho các API.

6. JWT – Xác thực phi trạng thái

Các API phải là phi trạng thái, bởi vậy xác thực cũng tương tự. JWT (Json Web Token) chính là ý tưởng. JWT gồm 3 phần:

Header: chứa kiểu của token, thuật toán hash.

Payload: Chứa các yêu cầu.

Signature (JWT không mã hóa payload mà chỉ kí xác thực).

Thêm xác thực loại JWT vào ứng dụng khá đơn giản và nhanh chóng:

Sau khi thêm, endpoint API đã được bảo vệ với JWT. Để truy cập vào các endpoint được bảo vệ, bạn cần phải cung cấp token trong trường header Authorization:

Hãy chú ý một điều rằng module JWT trên không phụ thuộc bất cứ lớp database nào, do tất cả token JWT có cơ chế tự xác thực, và chúng còn bao gồm cả giá trị thời gian sống.

Ngoài ra, bạn phải luôn luôn chắc chắn rằng tất cả các API endpoint trong ứng dụng sẽ chỉ được truy cập thông qua kết nối bảo mật sử dụng HTTPS.

Trong bài viết trước, chúng tôi đã giải thích chi tiết về phương pháp xác thực web. Tôi khuyến nghị các bạn hãy tìm hiểu thêm.

7. Sử dụng các request có điều kiện

Các request có điều kiện là các request HTTP được thực thi theo các cách khác nhau, phụ thuộc vào các header HTTP cụ thể. bạn có thể xem các header này như là điều kiện tiên quyết: nếu chúng gặp nhau, các request sẽ được thực thi theo các cách khác nhau.

Các request có điều kiện là các request HTTP được thực thi theo các cách khác nhau, phụ thuộc vào các header HTTP cụ thể

@RisingStack

Các header này sẽ cố gắng kiểm tra liệu một phiên bản tài nguyên được lưu trữ trên server có trùng với phiên bản của cùng một tài nguyên hay không. Vì lý do này, các header có thể là:

Timestamp của lần thay đổi gần nhất.

Một tag nào đấy, khác nhau tùy vào phiên bản.

Chúng chính là:

Last-Modified ( để chỉ ra lần gần nhất dữ liệu được chỉnh sửa ).

Etag ( để chỉ ra tag ).

If-Modified-Since (sử dụng với header Last-Modified ).

If-None-Match (sử dụng với header Etag ).

Client có thể thiết lập header If-Modified-Since và If-None-Match một lần khi nó cố gắng gửi request với cùng tài nguyên. Nếu response trả về là giống nhau, server chỉ đơn giản là phản hồi lại với mã status 304 - Not Modified và không gửi lại tài nguyên nữa.

8. Quản lý giới hạn rate (rate limiting)

Rate limiting được sử dụng để điều khiển việc một cunsumer có thể gửi đến API bao nhiêu request.

Để nói với API có bao nhiêu request đã được gửi, trong header hãy thiết lập như sau:

X-Rate-Limit-Limit: số lượng các request được cho phép trong một khoảng thời gian cho trước.

X-Rate-Limit-Remaining: the number of requests remaining in the same interval. số lượng các request cong lại trong cùng khoảng thời gian.

X-Rate-Limit-Reset: thời gian mà rate limit được thiết lập.

Phần lớn các framework HTTP hỗ trợ bằng các công cụ bên ngoài hay là các plugin. Ví dụ, nếu bạn sử dụng Koa, hãy thử package koa-ratelimit.

Chú ý rằng thời gian window có thể thay đổi tùy vào các nhà cung cấp API khác nhau – ví dụ đối với Github là 1 giờ, trong khi Twitter là 15 phút.

9. Tạo các document API đúng chuẩn

Các API được viết ra để mọi người có thể sử dụng chúng, hưởng lợi ích từ chúng. Do đó việc cung cấp các document đi kèm với các REST API là điều tối cần thiết.

Các project open-source sau đây có thể giúp bạn tạo ra các document cho API:

Nếu bạn muốn sử dụng sản phẩm đã host, bạn có thể dùng Apiary.

10. Đừng quên tương lai sáng lạn của API

Trong vài năm vừa qua, hai ngôn ngữ truy vấn lớn cho các API đã mọc lên: GraphQL của Facebook và Falcor của Netflix. Tại sao ta lại cần chúng đến thế?

Tưởng tượng một request tài nguyên RESTful như sau:

Nếu bạn có dự định bắt đầu phát triển một REST API chúng tôi hoặc tạo một phiên bản mới của API cũ, chúng tôi đã thu thập 4 ví dụ thực tế để giúp bạn:

Tôi mong là qua bài viết này, các bạn đã có một cái nhìn tổng thể về các API, tại sao các API nên được viết bằng Node.js.

Nguồn Techtalk.vn

Viết Api Document Với Apidocjs

Về việc viết document nói chung và API document nói riêng

Document là thứ rất quan trọng khi bàn giao một dự án hay cần tham khảo để bảo trì, phát triển dự án đó. Một số bạn dev sẽ nói mình viết code đẹp rồi, cứ vào đọc là hiểu ngay cần gì làm doc và thẳng thừng nói không với doc. Nhưng khi download một source code về, nhận code từ dev khác hay vào maintain một project thì khóc ròng vì không hiểu người ta viết gì cả. Vậy nên:

1. Nếu bạn định code cái gì, hãy dành thời gian ra viết một chút document cho nó 2. Nếu bạn không cập nhật document thì đừng viết nó ra

Với API, dù bạn viết code đẹp thế nào mà không có gì cho client tham khảo ngoài một API mẫu thì khối API bạn viết sẽ sớm trở thành thảm họa với những lỗi kinh điển như: sai kiểu dữ liệu gửi nhận, sai mã lỗi, tốn thời gian support client, mất kiểm soát khi nâng cấp API version… sau đó thì kiểu gì bạn cũng phải ngồi viết document.

npm install apidoc -g Các thức hoạt động

Folder api-document-output là output của chương trình được generate tự động, bạn không cần đụng tới nó, chỉ cần mở file index.html để xem kết quả.

Bắt đầu viết doc như sau, tạo một file có đuôi cùng với ngôn ngữ bạn dùng để viết API, trong trường hợp này là .js, viết toàn bộ thông tin về một API theo mẫu thế này:

/** * @api {get} /user/:id Request User information * @apiName GetUser * @apiGroup User * * @apiParam {Number} id Users unique ID. * * @apiSuccess {String} firstname Firstname of the User. * @apiSuccess {String} lastname Lastname of the User. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "firstname": "John", * "lastname": "Doe" * } * * @apiError UserNotFound The id of the User was not found. * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "error": "UserNotFound" * } */ apidoc -i api-document-source/ -o api-document-output/

Với param -i, -o đơn giản là input folder, output folder. Sau đó mở file index.html trong folder out put để xem kết quả. Giao diện đơn giản trình bày tất cả API trong một trang, navigate bằng menu bên trái, toàn bộ chi tiết trình bày ở giữa trang

Happy documentation 🙂