Axios là gì, xây dựng ứng dụng khai thác tin Vnexpress.net sử dụng Vue.js và axios

Các website lớn hiện nay đều cung cấp hệ thống API giúp cho chúng ta có thể viết các ứng dụng tương tác, ví dụ như với mạng xã hội Facebook, Google Plus chúng ta đều có các API để thực hiện các tương tác. Ở Việt nam một số các trang thương mại điện tử lớn cũng đã bắt đầu cung cấp các RESTfull API như Lazada, Sendo… hay hệ thống phát triển mở của FPT cũng có những API cho phép bạn thực hiện. Các hệ thống API này có thể sử dụng xác thực mở OAuth 2 hoặc cũng có thể không cần thiết. Chúng ta hoàn toàn có thể tạo ra các ứng dụng để làm việc với các hệ thống API này thông việc gọi đến các API được cung cấp sẵn. Các kiến thức trong bài viết giúp bạn hình dung được những gì cần thiết cho việc kết nối đó. Cuối bài viết chúng ta sẽ cùng thực hiện một ứng dụng khai thác tin tức từ Vnexpress.net.

1. Cơ bản về Axios

1.1 Axios là gì?

Axios là một HTTP client dựa được phát triển trên đối tượng Javascript Promise, nó có thể sử dụng trong các ứng dụng font-end Vue.js, React, Angular… Sử dụng Axios dễ dàng gửi đi các request HTTP bất đồng bộ đến các REST endpoint và thực hiện các chức năng CRUD.

Chúng ta gặp phải một số khái niệm có thể nhiều bạn chưa biết đến:

  • HTTP client là có thể là phần mềm, thư viện có thể thực hiện các yêu cầu (request) dạng HTTP đến máy chủ HTTP và nhận về các hồi đáp (reponse). Đơn giản hơn bạn có thể coi nó gần với một trình duyệt web.
  • Javascript Promise là một đối tượng giúp kiểm soát kết quả hoàn thành hay thất bại của một hành động bất đồng bộ trong Javascript (Tham khảo thêm Kiến thức về Javascript Promise).
    Vue.js, React, Angular là những framework Javascript hiện đang rất hot, giúp xây dựng những ứng dụng font-end linh hoạt hoạt động nhanh và mạnh mẽ.
  • REST endpoint là những điểm (URL) cung cấp các chức năng API cho phép chúng ta tương tác với một hệ thống, ví dụ khi chúng ta muốn tương tác với Lazada chúng ta có thể gửi các request HTTP đến các REST API do Lazada cung cấp.
  • CRUD viết tắt của Create, Read, Update, Delete là một thuật ngữ lập trình nói đến 4 phương thức quen thuộc khi làm việc với kho dữ liệu.

Tóm lại Axios là một “trình duyệt” trong Javascript giúp chúng ta thực hiện thao tác với các website hoặc API giúp xây dựng những ứng dụng font-end linh hoạt mạnh mẽ hơn.

1.2 Cài đặt Axios

Thư viện axios có thể cài đặt thông qua công cụ npm:

npm install axios

Hoặc chèn đường dẫn file Javascript trên các CDN:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Nếu bạn sử dụng framework Laravel, thư viện Axios đã được thiết lập sẵn trong file resources\assets\bootstrap.js:

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

và chỉ việc thực hiện npm install để cài đặt các gói đã được thiết lập sẵn.

1.3 Các phương thức của axios

1.3.1 Phương thức gửi yêu cầu HTTP

Các phương thức HTTP thường sử dụng nhiều nhất để khai thác dữ liệu là GET và POST. Axios có hai phương thức để thực hiện GET và POST dữ liệu.

axios.get('http://allaravel.com/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Đoạn mã này gửi một request với phương thức GET đến URL http://allaravel.com/user?ID=12345, nếu thành công kết quả sẽ được in ra console trong .then() và nếu lỗi thì in lỗi ra console trong .catch(). Bạn có thể tưởng tượng nó giống như việc bạn mở trình duyệt ra, gõ vào đường dẫn cần đến và chờ, nếu thông tin được hiển thị bạn sẽ đọc được, nếu không một thông báo lỗi hiển thị lên trên trình duyệt. Chú ý, tham số truyền vào (query string) có thể đưa vào phần tham số như sau:

axios.get('http://allaravel.com/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Tiếp theo chúng ta xem gửi dữ liệu với phương thức POST đến một URL như thế nào:

axios.post('http://allaravel.com/user', {
    name: 'FirebirD',
    email: 'firebird@allaravel.com',
    password: '123456'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Đoạn code trên thực hiện giống như chúng ta mở một form tạo mới user, nhập các dữ liệu vào và nhấn nút Gửi. Trên đây chúng ta gửi đi các yêu cầu đơn lẻ, nếu như muốn cùng một lúc gửi nhiều các yêu cầu lấy dữ liệu thì sao? Ví dụ tiếp theo gửi đi hai yêu cầu, một để lấy thông tin tài khoản, một để lấy thông tin đơn hàng.

function getAccountInfomation() {
  return axios.get('/account/12345');
}

function getOrderInfomation() {
  return axios.get('/order/12345');
}

axios.all([getAccountInfomation(), getOrderInfomation()])
  .then(axios.spread(function (account, order) {
    // Cả hai yêu cầu được hoàn thành
  }));

Các phương thức khác như DELETE, PUT, PATCH cũng được hỗ trợ. Bạn có thể tham khảo thêm trong tài liệu Axios. Tiếp theo, chúng ta sẽ tìm hiểu cách thức đưa thêm các thiết lập cấu hình trước khi gửi đi yêu cầu HTTP (với trình duyệt thường nó ngầm định nên bạn không để ý đến).

axios(url[, config])

Các yêu cầu HTTP có thể gửi đi bằng cú pháp ở trên, có thể truyền vào các cấu hình trong đối tượng config như sau:

{
  // URL đích đến của yêu cầu HTTP
  url: '/user',

  // Phương thức gửi yêu cầu có thể là GET, POST, DELETE, PUT...
  method: 'get', // default

  // URL cơ sở, nếu bạn có nhiều request đến một server sử dụng URL cơ sở để rút gọn tham số url ở trên
  // URL cơ sở có thể thiết lập toàn cục để dùng lại sau này.
  baseURL: 'https://allaravel.com/api/',

  // Thay đổi headers object của request.
  transformRequest: [function (data, headers) {
    // Thực hiện thay đổi tại đây

    return data;
  }],

  // Thay đổi headers object của phần response
  transformResponse: [function (data) {
    // Thực hiện thay đổi tại đây

    return data;
  }],

  // Thiết lập các giá trị cho headers object.
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // Thêm tham số vào query string
  params: {
    ID: 12345
  },

  // Cũng là tham số nhưng thêm vào body của request
  data: {
    firstName: 'Fred'
  },

  // Thiết lập thời gian chờ cho xử lý yêu cầu, nếu vượt quá sẽ hủy bỏ yêu cầu HTTP
  timeout: 1000,

  // Nhận diện yêu cầu là cross-site Access-Control hay không
  withCredentials: false, // default

  // Nhận diện URL có cần xác thực hay không và gửi đi các thông tin để xác thực.
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // Nhận diện dạng dữ liệu trả về từ server: arraybuffer, blob, document, json, text, stream
  responseType: 'json', // mặc định

  // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
  xsrfCookieName: 'XSRF-TOKEN', // default

  // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
  xsrfHeaderName: 'X-XSRF-TOKEN', // default

  // Quản lý tiến trình upload
  onUploadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },

  // Quản lý tiến trình download
  onDownloadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },

  // Kích thước dữ liệu tối đa hồi đáp từ máy chủ
  maxContentLength: 2000,

  // Kiểm tra trạng thái
  validateStatus: function (status) {
    return status >= 200 && status < 300; // default
  },

  // Số lần chuyển hướng cho phép khi gọi đến URL, nếu thiết lập 0 là không cho phép
  maxRedirects: 5, // mặc định

  // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // Thiết lập proxy
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // Xác định cancel token sử dụng để hủy bỏ yêu cầu
  cancelToken: new CancelToken(function (cancel) {
  })
}

1.3.2 Cấu trúc dữ liệu hồi đáp

Đối tượng response được trả về từ server có cấu trúc như sau:

{
  // Dữ liệu cần lấy từ máy chủ
  data: {},

  // Mã trạng thái HTTP của yêu cầu
  status: 200,

  // Mô tả trạng thái tương ứng với mã trạng thái ở trên
  statusText: 'OK',

  // Thông tin header của hồi đáp (response)
  headers: {},

  // config được thiết lập trước khi gửi request
  config: {},

  // là thực thể của ClientRequest nếu sử dụng Node.js và XMLHttpRequest trong trình duyệt
  request: {}
}

Với cấu trúc này, khi một request HTTP được gửi đến server chúng ta có thể quản lý được các thông tin trả về từ server, hãy xem ví dụ sau:

axios.get('http://allaravel.com/user/12345')
  .then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

1.3.3 Hook API

Trong quá trình gửi đi một yêu cầu, ngay trước khi gửi chúng ta có thể mong muốn thực hiện một số công việc hoặc ngay khi nhận được response cũng vậy. Ví dụ thực thế, nếu bạn muốn là một thanh trạng thái hiển thị phần trăm công việc đang thực hiện, bạn cần biết các thời điểm ngay khi gửi request và ngay khi nhận được response. Có thể sử dụng các thuật ngữ như Hook API hoặc Interceptor cho những gì mô tả ở trên. Với axios bạn tham khảo đoạn mã dưới đây kết hợp với thư viện nprogress:

axios.interceptors.request.use(function (config) {
	NProgress.start();
	return config;
}, function (error) {
	return Promise.reject(error);
});

axios.interceptors.response.use(function (response) {
    NProgress.done();
    return response;
}, function (error) {
    return Promise.reject(error);
});

1.3.4 Kiểm soát lỗi khi gửi yêu cầu HTTP với Axios

Kiểm soát lỗi chi tiết là rất cần thiết, với từng lỗi cụ thể chúng ta sẽ có những xử lý riêng biệt tăng cường trải nghiệm người dùng với sự linh hoạt của ứng dụng:

axios.get('http://allaravel.com/user/12345')
  .catch(function (error) {
    if (error.response) {
      // Lỗi khi server nhận được request và không xử lý được, các lỗi này có mã lỗi trong dải 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // Lỗi khi request được tạo ra nhưng server không hồi đáp, khi đó error.request là một thực thể của XMLHttpRequest
      console.log(error.request);
    } else {
      // Lỗi khi thiết lập request
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

1.3.5 Hủy bỏ một yêu cầu

Hủy bỏ yêu cầu là một chức năng cần thiết, bạn tưởng tượng người dùng click vào nút gửi đơn hàng và mỗi đơn hàng xử lý trong 10 giây, tuy nhiên ngay sau khi click người dùng lại muốn hủy bỏ yêu cầu để sửa lại đơn hàng này với số lượng sản phẩm nhiều hơn, như vậy hủy bỏ yêu cầu là rất cần thiết.

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.post('http://allaravel.com/order', {
  data: {
     'product_id': 234,
     'quantity': 3
  },
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Hủy bỏ yêu cầu', thrown.message);
  } else {
    // Quản lý lỗi ở đây
  }
});

// Người dùng muốn hủy yêu cầu tạo đơn hàng mới
source.cancel('Hủy yêu cầu tạo đơn hàng mới.');

2. Xây dựng ứng dụng khai thác tin tức Vnexpress.net với Vue.js + Axios

Trong phần 1 hiểu Axios là gì? và biết cách sử dụng thư viện này, phần tiếp theo chúng ta sẽ cùng nhau xây dựng một ví dụ cụ thể để có thể hiểu rõ hơn về cách thức áp dụng Axios. Ví dụ của chúng ta là một trang khai thác tin tức từ Vnexpress.net.

Mô hình ứng dụng

Do Vnexpress.net không cung cấp API để khai thác tin nên chúng ta sẽ sử dụng RSS2JSON để chuyển đổi từ RSS sang thành một API trả về dữ liệu Json. Cấu trúc dữ liệu trả về có dạng Json như hình ảnh dưới:

Chuyển RSS Vnexpress.net thành Json

Ok, như vậy chúng ta đã có API cung cấp dữ liệu, tiếp theo chúng ta sẽ sử dụng Vue.js và Axios để khai thác tin tức và trình bày lại trang.

 

2.2 Xây dựng trang khai thác tin

Diễn giải ứng dụng:

  1. Điểm vào của ứng dụng là sử dụng axios.get để lấy dữ liệu từ API do RSS2JSON cung cấp, dữ liệu trả về dạng JSON.
  2. Sử dụng v-for của Vue.js để lặp lại qua mảng results và hiển thị từng item (bài viết) trong mảng này, chúng ta style bằng bootstrap.

Do thời gian có hạn nên ứng dụng khai thác tin chỉ tạm dừng ở tính năng cơ bản để giúp bạn đọc hiểu rõ hơn về axios, hẹn có thời gian chúng ta sẽ làm một ứng dụng khai thác tin mạnh mẽ và đầy đủ tính năng hơn.

3. Tại sao dùng Axios?

Hiện tại có rất nhiều các HTTP Client dạng Javascript có thể kể đến ngoài Axios như việc sử dụng jQuery, phương thức fetch() được hỗ trợ từ ES6, SuperAgent, Qwest… Tuy nhiên Axios có nhiều ưu điểm như sau:

  • Axios xây dựng dựa trên nền tảng Promise do đó nó kế thừa các ưu điểm của Promise.
  • Cho phép thực hiện các hook (intercept) ngay khi gửi request và nhận response.
  • Cho phép hủy yêu cầu, đây là một chức năng mà các thư viện khác không có.

Lời kết

Qua bài viết, tôi tin rằng bạn đã trả lời được câu hỏi Axios là gì?, Tại sao dùng Axios?. Axios là HTTP Client giúp xây dựng các ứng dụng kết nối từ nhiều nguồn dữ liệu dễ dàng, nếu có sự liên tưởng bạn sẽ thấy nó giống với GuzzleHttp trong PHP. Axios là phần công cụ giúp lấy dữ liệu dễ dàng cho các framework như Vue.js, React.js, Angular… xây dựng các ứng dụng font-end linh động và dễ dàng. Trong thời gian tới, nếu có thời gian chúng ta sẽ cùng nhau xây dựng một trang khai thác tin như trang baomoi.com, các bạn đón đọc nhé.

One thought on “Axios là gì, xây dựng ứng dụng khai thác tin Vnexpress.net sử dụng Vue.js và axios

Add Comment