Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[24/06/2023] NEW UPDATE: Add createAPICaller, createAPICallers functions. Update app/apis (add class, utils) #95

Open
NguyenAnhTuan1912 opened this issue Jun 24, 2023 · 0 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@NguyenAnhTuan1912
Copy link
Collaborator

NEW, CHANGES AND GUIDES

Issue này dùng để thông báo một số thay đổi và hướng dẫn dùng 2 hàm mới để tạo và quản lý api caller(s). Đây là một trong những nỗ lực của quá trình tái cấu trúc mã nguồn :')

NEW, CHANGES

  • Class apis/axios/class/APIsOptions.
  • Blog apis (get, post, delete).
  • Creator: createAPICaller (1), createAPICaller (2). Với mục đích của hàm đầu tiên (1) là dùng để rút ngắn lại quá trình định nghĩa 1 apis (bởi vì có thể 5 cái api callers sẽ có cách defined y hệt nhau, khác mỗi url). Hàm thứ 2 (2) là dùng để tạo ra một group apis có liên quan tới nhau, rất tiện cho việc quản lý. Hàm (2) được xây dựng dựa trên hàm (1).
  • Thêm apis/axios/utilsmới
    • getQueryString(query: {[key: string]: any}): string`: dùng để chuyển query object thành query string, phù hợp với url.
  • Thêm screen BlogCommentScreen. Screen này thì mới làm giao diện thôi, chưa có thực hiện chức năng, nhưng coi như là phần khởi tạo cho nó vậy.

EXPLAINS

Trong phần này thì có 2 thứ để giải thích là API Options và các hàm tạo API Caller. Hầu hết những sự thay đổi mới lần này đều nằm ở trong api/axios.

APIOptions

Là một Class, dùng dể tạo ra một object dùng để hỗ trợ cho việc gọi và thiết kế api (thiết kế hàm tại api nữa), lý do tạo ra một object để sau này mình có thể dễ dàng nâng cấp, thêm thắt để hỗ trợ cho mục đích trên. Bao gồm các thuộc tính.

axiosInstance: AxiosInstance (Property)

Thuộc tính này lưu lại ref của Axios Instance, dùng để hỗ trợ cho việc request về server, cái này thì ae mình dùng nhiều rồi.

headers: AxiosHeaders (Property)

Thuộc tính này chứa phần headers cho mỗi lần request.

method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" (Property)

Tên phương thức của HTTP khi request về server.

getQueryString(query: {[key: string]: any}): string

Phương thức này dùng để tạo ra một query ở dạng chuỗi, dùng cho url, từ một object.

Ngoài ra thì còn một class nữa mà thôi, class đó kế thừa từ class trên và thêm một số thuộc tính, phương thức nhỏ. Túm lại, object này dùng để hỗ trợ cho việc thiết kế api, hỗ trợ cho các hàm tạo api.


createAPICaller(url: string, options: APIOptionsProps, callBack: (data: any, call: (data: any) => Promise<AxiosResponse>) => Promise<any>): (data: string | { [key: string]: any }, headers: AxiosHeaders) => Promise<any>

Hàm này sẽ nhận vào 3 thông số:

  • url: là một url để request tới để lấy, gửi dữ liệu. Cái này thì ae không lạ gì nữa rồi, nhưng t vẫn ví dụ: http://localhost:7500/v1/blog/get_multiple
  • options: cái này thì chính là object APIOptions ở trên.
  • callBack: bình thường mình viết api sao thì hàm này có mục đích y chang vậy, tuy nhiên thì hơi khác một tí. Mục đích của callBack là để custom, thêm thắt, sửa đổi một số thứ trước khi gọi api và sau khi nhận dữ liệu về. Nhận vào 2 tham số là datacall. data ở đâu thì hết gạch đầu dòng này là biết, còn call là hàm dùng để gọi api, nhận vào tham số là data chính là cái data mà callBack nhận vào á.

Hàm này sẽ trả về một function dùng để gọi api mỗi khi cần

function(data: any, headers: AxiosHeaders): Promise<any>

Data mà mình truyền vào hàm này chính là datacallBack sẽ nhận được.

createAPICallers<CallerOptions>(options: CreateAPICallersOptions<CallerOptions>): APICallers<CallerOptions>

Hàm này dùng để tạo ra một nhóm apis có config giống nhau, dùng để quản lý các api dễ hơn, dễ năng cấp hơn. Khác với createAPICaller thì thằng này nó chỉ nhận một tham số:

  • options. options này là object được extended từ APIOptions và các tham số mới như là:
  • baseUrl: là một phần của url. Nó sẽ là phần cố định để xây dựng lên một url hoàn chỉnh có từng callers.
  • path: là phần cùng với baseUrl để xây dựng lên một url hoàn chỉnh. Tuy nhiên thì path này sẽ dùng chung cho mọi callers.
  • callers: là danh sách setup cho các callers nhận vào các thuộc tính giống với APIoptions và cả các thuộc tính giống options (trừ baseUrlcallers). Ngoài ra thì nó còn có thêm một thuộc tính nữa là fn, thuộc tính này y hệt với callBack của createAPICaller.

Hàm này sẽ trả về một list các function (giống với function trả về khi dùng createAPICaller) dựa theo callers

{
  [Key in keyof Callers]: (data: any, headers: AxiosHeaders) => Promise<any>
}

GUIDES

Giờ thì t sẽ hướng dẫn sử dụng sơ qua cái này. Ví dụ t sẽ chuyển getBlogAPIgetBlogs từ trong apis/axios/index về thành API của Blog cho dễ quản lý.
Original

export const getBlogAPI = async (query) => {
  try {
    let user = injectedStore.getState().user.currentUser;
    if(user) query += `&userId=${user._id}`;
    const response = await axios.get(`${API_ROOT}/v1/blog/get_one?${query}`);
    return response.data;
  } catch (error) {
    console.error(error.message);
  }
}

export const getBlogsAPI = async (query = "?limit=5&skip=0") => {
  try {
    let user = injectedStore.getState().user.currentUser;
    if(user) query += `&userId=${user._id}`;
    const response = await axios.get(`${API_ROOT}/v1/blog/get_multiple?${query}`);
    return response.data;
  } catch (error) {
    console.error(error.message);
  }
}

Giờ thì tạo một folder mới có tên là blog, trong blog tạo thêm một folder là get và trong get tạo thêm một file index.js. Tóm lại mình sẽ có apis/axios/blog/get/index.js
image

Tiếp theo, import createAPICallers vào và dùng như sau

export const {
  getBlogAPI,
  getBlogsAPI,
  getBlogCommentsAPI
} = createAPICallers({
  baseUrl: `${API_ROOT}/v1/blog`,
  callers: {
    getBlogsAPI: {
      path: "/get_multiple",
      fn: async function(data, call) {
        try {
          console.log("CALLER: ", call)
          let response = await callWithGlobalLoading(async () => call(data));
          return response;
        } catch (error) {
          console.error(error.message);
        }
      }
    },
    getBlogAPI: "/get_one",
    getBlogCommentsAPI: {
      path: "/get_comments",
      method: "POST"
    }
  }
});
  • Với getBlogsAPI, thì mình truyền vào cho nó path = /get_multiple (để dễ nhận biết, chỗ này thì baseUrl càng cần endpoint thì việc quản lý sẽ dễ dàng hơn), fn là một function như ở trên, method, axiosInstance không cần setup, bởi vì nó đã được setup mặc định, ngoài ra nếu ở trên (ngoài callers) có thì nó sẽ dùng cái ở đây. Như tụi m có thể thấy thì t muốn custom lại mỗi khi lấy blogs. Nó sẽ hiện lên global loading mỗi khi request dữ liệu.
  • Với getBlogAPI thì mình truyền luôn path của nó vào, và sẽ được tự động setup mặc định.
  • Với getBlogCommentsAPI thì mình lại truyền vào object, nhưng lần này không truyền fn mà truyền method. method của caller sẽ ghi đè lên cái method được setup chung.

Ngoài ra thì mình còn có thể dùng createAPICaller để setup như sau

let baseUrl = `${API_ROOT}/v1/blog`
export const getBlogAPI = createAPICaller(baseUrl + "/get_one");
export const getBlogsAPI = createAPICaller(
  baseUrl + "/get_multiple",
  undefined,
  async function(data, call) {
    try {
      console.log("CALLER: ", call)
      let response = await callWithGlobalLoading(async () => call(data));
      return response;
    } catch (error) {
      console.error(error.message);
    }
  }
);
export const getBlogCommentsAPI = createAPICaller(baseUrl + "/get_comments");
  • Với getBlogAPI và getBlogCommentsAPI thì mình chỉ cần truyền vào url là sẽ được tự động setup.
  • Với getBlogsAPI thì mình sẽ setup theo kiểu khác, thông số thứ 2 là options nhưng mình muốn dùng default options cho nên là truyền cho nó undefined. Ngoài ra thì mình dùng callBack y hệt với fn trong caller.

Với các phương thức khác như là POST, PUT, DELETE, PATCH thì tương tự. khuyến khích tụi m là nên để cùng các phương thức với nhau như t đã làm. Để đỡ khỏi phải setup nhiều lần cho mỗi method khác nhau.

@NguyenAnhTuan1912 NguyenAnhTuan1912 added the documentation Improvements or additions to documentation label Jun 24, 2023
@NguyenAnhTuan1912 NguyenAnhTuan1912 self-assigned this Jun 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant