Connect front-end React and back-end Express
Có lẽ khi mới bắt đầu bước vào con đường lập trình website thì còn khá nhiều anh em DEV mơ hồ về việc một website thực thụ có cả front end và back end tích hợp với nhau như thế nào. Chính vì thế, hôm nay mình sẽ DEMO cho các bạn cách để front end và back end giao tiếp với nhau. Trong bài viết này mình chỉ dừng lại ở mức độ minh họa với front end reactjs và back end expressjs, tạm thời chưa tích hợp DB. Các bạn có thể tham khảo cách kết nối với DB tương ứng ở trang tài liệu chính thức nhé
Oke bắt đầu thôi
Phần Server
Chúng ta sẽ bắt đầu với phần Server trước nhé. Ta tạo 1 folder ví dụ: react-express. Sau đó mở bằng vscode và bắt dầu dự án với CLI:
npm init
Enter các thông tin của project, các bạn có thể bỏ qua cũng không sao. Sau bước này ta được 1 file package.json
để quản lí các dependencies
của dự án.
Tại đây ta cài đặt 3 modules là express, concurrently, cors
. Express
thì chắc không cần nói đến nữa vì nó khá là quen thuộc với các anh em DEV, còn module concurrently
dùng để nối 2 hoặc nhiều script cho phép chúng chạy cùng 1 lúc (các script
trong file package.json
) lát nữa ta sẽ viết một vài script cấu hình cho project, tạm thời các bạn chưa cần quan tâm đến module này, mình sẽ nói rõ hơn trong phần kế tiếp. Còn module cors (Cross-orrigin Resource Sharing
), trước đây khi chưa có CORS thì ta không có cách nào để request đến một endpoint khác domain vì lý do bảo mật, và mặc định trình duyệt sẽ chặn các request (HEAD, GET, POST) đến domain này nhằm bảo vệ các tài nguyên. Điều này có nghĩa, ta sẽ không nhận được respond khi fetch data từ client xuống server. Chính vì vậy mà module cors giúp ta disable CORS
đi và nhận được respond từ phía server. Topdev có một bài viết khá chi tiết về vấn đề này, các bạn đọc để hiểu rõ hơn nhé
npm install express concurrently cors --save
Ở đây mình cài thêm nodemon
để tiện cho việc Debug không cần phải restart server
bằng tay. Các bạn có thể bỏ qua module này cũng không sao
npm install nodemon --save-dev
Sau khi hoàn tất ta chỉnh sửa script start server
một tí để dùng thằng nodemon vừa cài. Các bạn có thể bỏ qua bước này nếu ko dùng nodemon
Ở đây mình chỉ dựng một server
đơn giản nên chỉ cần tạo 1 file server.js để DEMO. Trường hợp code back-end
của bạn phức tạp hơn thì hãy tạo 1 folder server
cùng cấp với package.json đề chứa nó nhé
Mở file server.js, mình sẽ dựng một server với route duy nhất là GET: /api/products
. Nó sẽ trả về hard-data
là một array gồm nhiều object product . Trường hợp bạn có connect DB thì tại đây bạn call api lấy dữ liệu từ DB nha
const express = require('express')
const cors = require('cors')
const PORT = 8080;
const app = express()
app.use(cors())
app.get('/api/products', function(req, res){
const products = [
{ p_id: 1, p_name: 'Bánh mì chả cá', p_price: '15.000', },
{ p_id: 2, p_name: 'Bún mắm nêm', p_price: '25.000', },
{ p_id: 3, p_name: 'Gỏi cuốn', p_price: '20.000', },
{ p_id: 4, p_name: 'Súp cua', p_price: '18.000', },
]
res.json(products)
})
app.listen(PORT, () => console.log(`Server is starting at PORT ${PORT}`))
Các bạn nên dùng một port khác 3000 để tránh đụng độ với port mặc định của reactjs nhé
Bây giờ ta run server và test thử route vừa định nghĩa có hoạt động chưa nè
npm run server
(script vừa rồi ta custom)
Qua browser và request GET
đến http://localhost:8080
và xem kết quả. Trường hợp bạn không dùng nodemon
thì chạy bằng CLI: npm start
Và kết quả thành công. Ở đây browser mình hiển thị respond dưới dạng json
khá dễ nhìn là do mình có cài 1 chrome extention là JSONView nhé
Phần Client
Tiếp đến, ta qua front-end
và new 1 project bằng tool create-react-app
của react
npx create-react-app client
Mình tạo 1 project có tên là client
để Demo nhé. Sau khi hoàn tất, ta mở file package.json
của folder client và thêm 1 thuộc tính proxy
trỏ tới server của ta. Bằng cách thêm thuộc tính này khi ta call api nó sẻ tự biết đi đến base url
nào để thực hiện fetch data
Mình sẻ viết một component
để hiển thị các products
nhận được khi fetch api
đến server
import React, { useState, useEffect } from 'react';
import './style.css'
function Products() {
const [products, setProducts] = useState([]);
useEffect(() => {
async function fetchListProducts(){
try {
const urlRequest = "http://localhost:8080/api/products"
const respond = await fetch(urlRequest)
const respondData= await respond.json()
setProducts(respondData)
} catch (error) {
console.log("Failed to fetch..." + error.message)
}
}
fetchListProducts()
}, []);
return (
<div className="container">
<table className="products">
<thead className="product__column">
<tr>
<th className="product__key">ID</th>
<th className="product__key">Name</th>
<th className="product__key">Price</th>
</tr>
</thead>
<tbody className="product__row">
{ products.map(product =>
<tr key={product.p_id}>
<td>{product.p_id}</td>
<td>{product.p_name}</td>
<td>{product.p_price}</td>
</tr>
)}
</tbody>
</table>
</div>
);
}
export default Products;
Run project ở phía Client:
Tada, có vẻ thành công rồi nhĩ
Quay trở lại với file package.json
phía server ta bổ sung thêm các script để có thể start cùng lúc cả server
và client
Script "client" là để gọi đến script npm start
trong client, script "dev" dùng để run cùng lúc server và client. Đến đây ta thấy tác dụng của module concurrently
, nó giúp ta thực hiện cùng lúc 2 script là npm run server
và npm run client
. Ở đây ta cần chú ý phải chạy script run server trước để nó lắng nghe các request từ client, nếu đão ngược thứ tự thì việc request api
sẽ lỗi và không có data respond
Oke từ giờ khi chạy project ta chỉ cần chạy script
npm run dev
Vậy là xong, quá dễ dàng đúng không nè. Hi vọng bài viết này sẽ giúp các bạn có cái nhìn rõ hơn về việc giao tiếp giữa client và server
Github project: https://github.com/Nguyen-Quoc-Thai/react-express-connection/tree/master
Chúc các bạn thành công !
Writer: Quốc Thái
Nhận xét
Đăng nhận xét