Stori.
Quy tắc trả response API
5 min read

Quy tắc trả response API

API

I. Cấu trúc response

{
    "status": number,
    "message": string,
    "data": any
}

II. Endpoint

  • Đa ngôn ngữ
  • // Cau truc
    const BASE_URL = `https://api.midu.vn/v1/api/${lang}`
    // Vi du
    const BASE_URL = "https://api.midu.vn/v1/api/vi"
  • Định dạng endpoint
  • //Su dung lang === vi
    const BASE_URL = `https://api.midu.vn/v1/api/${lang}`
    //Su dung gach noi lien ket cac tu
    const CLINICAL_PROTOCOLS_ENDPOINT = "/clinical-protocols"
    
    console.log(`${BASE_URL}${CLINICAL_PROTOCOLS_ENDPOINT}`)
    // => https://api.midu.vn/v1/api/vi/clinical-protocols

    III. Quy tắc tiêu chuẩn - Naming rules

    1. Dùng tiếng Anh

    Luôn sử dụng tiếng Anh để đặt tên hàm và biến.

    /* Bad */
    const hoTen = "Trạng Tí"
    const banBe = ["Sửu Ẹo", "Dần Béo", "Cả Mẹo"]
    
    /* Good */
    const fullName = "Trạng Tí"
    const friends = ["Sửu Ẹo", "Dần Béo", "Cả Mẹo"]

    2. Quy ước đặt tên

    Camel sase và quan trọng là consistency (nhất quán).

    /* Bad */
    const page_count = 5
    const isUser = true
    
    /* Good */
    const pageCount = 5
    const isUser = true

    3. Nguyên tắc S-I-D

    Short, Intuitive, Descriptive.

  • Short (ngắn gọn): tên không được dài, không phải mất thời gian để gõ và nhớ.
  • Intuitive (tự nhiên): tên khi đọc lên phải cho cảm giác xuôi tai, gần gũi với văn nói.
  • Descriptive (súc tích): tên phải mô tả được ý nghĩa, tác dụng của nó, bằng cách hiệu quả nhất.
  • /* Bad */
    const totalNumberOfPublishedArticles = 10 // tên quá dài
    const a = 5 // "a" không mô tả được số 5 để làm gì
    const isDisplayable = a > 5 // "isDisplayable" nghe không tự nhiên lắm
    
    /* Good */
    const totalArticles = 10
    const postCount = 5
    const shouldDisplay = postCount > 5

    4. Tránh viết tắt

    Không được sử dụng từ viết tắt.

    /* Bad */
    function onItmClk(ev) { }
    
    /* Good */
    function onItemClick(event) { }

    5. Tránh lặp từ

    Tận dụng context để đặt tên không lặp từ.

    class User {
        /* Bad */
        updateUserProfile() { }
    
        /* Good */
        updateProfile() { }
    }

    6. Số ít, số nhiều

    Áp dụng ngữ pháp số nhiều của tiếng Anh.

    /* Bad */
    const friend = ["Sửu Ẹo", "Dần Béo", "Cả Mẹo"]
    
    /* Good */
    const friends = ["Sửu Ẹo", "Dần Béo", "Cả Mẹo"]

    7. Tên hàm kiểu A/HC/LC

    Đối với tên hàm, có một kiểu đặt tên cực kỳ phổ biến mà có lẽ các bạn ít nhiều cũng đã từng gặp qua. Kiểu đó có dạng như sau:

    prefix? + action (A) + high context (HC) + low context? (LC)
    Note image

    8. Actions

    Động từ chỉ hành động của hàm

    get: Truy xuất/lấy dữ liệu.

    class User {
        getRole() {
            return this.role;
        }
    }
    user.getRole();

    set: Gán giá trị cho biến.

    class User {
        setRole(newRole) {
            this.role = newRole;
        }
    }
    user.setRole("Admin");

    reset: Đặt lại giá trị/trạng thái ban đầu.

    class User {
        resetRole() {
            this.role = "User";
        }
    }
    user.resetRole();

    fetch: Gửi request để lấy dữ liệu.

    function fetchUsers() {
        return fetch("https://api.viblo.asia/users", {...});
    }

    remove: Loại bỏ một phần tử khỏi mảng, danh sách, hoặc tập hợp (cần lưu ý điểm khác biệt giữa remove và delete).

    function removeItem(name, items) {
        return items.filter((itemName) => itemName !== name);
    }
    const initialItems = ["Giày", "Dép", "Quần áo"];
    removeItem("Dép", initialItems); // ["Giày", "Quần áo"]

    delete: Xóa bỏ hoàn toàn sự tồn tại của một cá thể.

    function deletePost(id) {
        return database.find({ id }).delete();
    }

    create: Tạo dữ liệu mới.

    function createRole(roleInfo) {
        return database.create(roleInfo);
    }

    handle: Xử lý sự kiện hoặc callback (ngoài handle thì on cũng hay được sử dụng).

    function handleClick(event) {
        console.log(event.target);
    }
    button.addEventListener("click", handleClick);

    9. Context

    Bối cảnh xử lý của hàm

    Hiểu đơn giản thì context là mục đích của hàm, hàm tồn tại để xử lý cái gì. Ví dụ:

    /* "Role" là context của hàm, hàm tồn tại để tạo role  */
    function createRole(roleInfo) { }
    
    /* "RecentPosts" là context của hàm, với "Recent" gọi là Low Context,
     và "Posts" gọi là High Context, hoặc có thể ngược lại */
    function getRecentPosts(user) { }

    Trong một số trường hợp, có thể bỏ qua không cần dùng context. Ví dụ như khi hàm được khai báo trong một class, hoặc khi hàm đó chuyên được dùng để xử lý một kiểu dữ liệu nào đó:

    /* Class Role đã là context của hàm */
    class Role {
        create(roleInfo) { }
    }
    
    /* Sort chuyên được dùng để sắp xếp danh sách/mảng,
     không cần thiết phải thêm sortList hay sortArray */
    function sort(condition, list) { }

    10. Prefixes

    Tiền tố giúp tăng ý nghĩa của hàm/biến

    is: Mô tả đặc điểm hoặc trạng thái của context (thường là boolean).

    const color = "blue"
    const isBlue = color === "blue" // đặc điểm
    const isPresent = true // trạng thái
    
    if(isBlue && isPresent) {
        console.log("Blue is present");
    }

    has: Xác định sự tồn tại hoặc trạng thái của context (thường là boolean).

    /* Bad */
    const isProductsExist = productCount > 0 // sai ngữ pháp
    const areProductsPresent = productCount > 0 // chưa gọn, đọc không xuôi tay lắm
    
    /* Good */
    const hasProducts = productCount > 0

    should: Thể hiện điều kiện sẽ xảy ra của một hành động (thường là boolean).

    function shouldUpdateUrl(url, expectedUrl) {
        return url !== expectedUrl;
    }

    min/max: Mô tả giới hạn của context (thường là numeric).

    function getPosts(posts, minPosts, maxPosts) {
        return posts.slice(0, randomBetween(minPosts, maxPosts));
    }

    prev/next: Thể hiện sự chuyển từ trạng thái cũ sang trạng thái mới.

    function fetchPosts() {
        const prevPosts = this.state.posts;
        const fetchedPosts = fetch(...);
        const nextPosts = concat(prevPosts, fetchedPosts);
        this.setState({ posts: nextPosts });
    }

    Share this article

    Share:
    Read Next Article