ExpressJS - API RESTFul
Một API luôn cần thiết để tạo ứng dụng di động, ứng dụng trang đơn, sử dụng lệnh gọi AJAX và cung cấp dữ liệu cho khách hàng. Một kiểu kiến trúc phổ biến về cách cấu trúc và đặt tên cho các API này và các điểm cuối được gọi làREST(Representational Transfer State). HTTP 1.1được thiết kế lưu ý các nguyên tắc REST. REST được giới thiệu bởiRoy Fielding vào năm 2000 trong các luận án về việc điền vào giấy của mình.
Các phương thức và URI RESTful cung cấp cho chúng tôi hầu hết mọi thông tin cần thiết để xử lý một yêu cầu. Bảng dưới đây tóm tắt cách sử dụng các động từ khác nhau và cách đặt tên các URI. Chúng tôi sẽ tạo ra một API phim về cuối; Bây giờ chúng ta hãy thảo luận về cách nó sẽ được cấu trúc.
phương pháp | URI | Chi tiết | Chức năng |
---|---|---|---|
ĐƯỢC | /phim | An toàn, có thể truy cập được | Nhận danh sách tất cả các bộ phim và thông tin chi tiết của chúng |
ĐƯỢC | / phim / 1234 | An toàn, có thể truy cập được | Nhận thông tin chi tiết của Movie id 1234 |
BÀI ĐĂNG | /phim | N / A | Tạo một bộ phim mới với các chi tiết được cung cấp. Phản hồi chứa URI cho tài nguyên mới được tạo này. |
ĐẶT | / phim / 1234 | Idempotent | Sửa đổi id phim 1234 (tạo một id nếu nó chưa tồn tại). Phản hồi chứa URI cho tài nguyên mới được tạo này. |
XÓA BỎ | / phim / 1234 | Idempotent | Id phim 1234 nên bị xóa, nếu nó tồn tại. Phản hồi phải chứa trạng thái của yêu cầu. |
XÓA hoặc ĐẶT | /phim | không hợp lệ | Nên không hợp lệ. DELETE và PUT nên chỉ định tài nguyên nào họ đang làm việc. |
Bây giờ chúng ta hãy tạo API này trong Express. Chúng tôi sẽ sử dụng JSON làm định dạng dữ liệu truyền tải của mình vì nó dễ làm việc với JavaScript và có các lợi ích khác. Thay thế của bạnindex.js nộp hồ sơ với movies.js tập tin như trong chương trình sau.
index.js
var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
var app = express();
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());
//Require the Router we defined in movies.js
var movies = require('./movies.js');
//Use the Router on the sub route /movies
app.use('/movies', movies);
app.listen(3000);
Bây giờ chúng ta đã thiết lập xong ứng dụng của mình, hãy tập trung vào việc tạo API.
Bắt đầu bằng cách thiết lập tệp phim.js. Chúng tôi không sử dụng cơ sở dữ liệu để lưu trữ phim mà đang lưu trữ chúng trong bộ nhớ; vì vậy mỗi khi máy chủ khởi động lại, các phim do chúng tôi thêm vào sẽ biến mất. Điều này có thể dễ dàng được bắt chước bằng cách sử dụng cơ sở dữ liệu hoặc tệp (sử dụng mô-đun fs nút).
Khi bạn nhập Express, hãy tạo một Bộ định tuyến và xuất nó bằng module.exports -
var express = require('express');
var router = express.Router();
var movies = [
{id: 101, name: "Fight Club", year: 1999, rating: 8.1},
{id: 102, name: "Inception", year: 2010, rating: 8.7},
{id: 103, name: "The Dark Knight", year: 2008, rating: 9},
{id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];
//Routes will go here
module.exports = router;
NHẬN các tuyến đường
Hãy để chúng tôi xác định lộ trình GET để nhận tất cả các bộ phim -
router.get('/', function(req, res){
res.json(movies);
});
Để kiểm tra xem điều này có hoạt động tốt hay không, hãy chạy ứng dụng của bạn, sau đó mở thiết bị đầu cuối của bạn và nhập -
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies
Phản hồi sau sẽ được hiển thị:
[{"id":101,"name":"Fight Club","year":1999,"rating":8.1},
{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},
{"id":104,"name":"12 Angry Men","year":1957,"rating":8.9}]
Chúng tôi có một lộ trình để lấy tất cả các bộ phim. Bây giờ chúng ta hãy tạo một lộ trình để lấy một bộ phim cụ thể theo id của nó.
router.get('/:id([0-9]{3,})', function(req, res){
var currMovie = movies.filter(function(movie){
if(movie.id == req.params.id){
return true;
}
});
if(currMovie.length == 1){
res.json(currMovie[0])
} else {
res.status(404);//Set status to 404 as movie was not found
res.json({message: "Not Found"});
}
});
Điều này sẽ giúp chúng tôi nhận được các bộ phim theo id mà chúng tôi đã cung cấp. Để kiểm tra đầu ra, hãy sử dụng lệnh sau trong thiết bị đầu cuối của bạn:
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies/101
Bạn sẽ nhận được phản hồi sau -
{"id":101,"name":"Fight Club","year":1999,"rating":8.1}
Nếu bạn truy cập vào một tuyến đường không hợp lệ, nó sẽ tạo ra một cannot GET error trong khi nếu bạn truy cập một tuyến hợp lệ với id không tồn tại, nó sẽ tạo ra lỗi 404.
Chúng ta đã hoàn thành các tuyến đường GET, bây giờ chúng ta hãy chuyển sang POST lộ trình.
ĐĂNG tuyến đường
Sử dụng tuyến đường sau để xử lý POSTed dữ liệu -
router.post('/', function(req, res){
//Check if all fields are provided and are valid:
if(!req.body.name ||
!req.body.year.toString().match(/^[0-9]{4}$/g) ||
!req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
res.status(400);
res.json({message: "Bad Request"});
} else {
var newId = movies[movies.length-1].id+1;
movies.push({
id: newId,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
});
res.json({message: "New movie created.", location: "/movies/" + newId});
}
});
Thao tác này sẽ tạo một bộ phim mới và lưu trữ nó trong biến phim. Để kiểm tra tuyến đường này, hãy nhập mã sau vào thiết bị đầu cuối của bạn -
curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies
Phản hồi sau sẽ được hiển thị:
{"message":"New movie created.","location":"/movies/105"}
Để kiểm tra xem điều này có được thêm vào đối tượng phim hay không, hãy chạy yêu cầu nhận cho /movies/105lần nữa. Phản hồi sau sẽ được hiển thị:
{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}
Hãy để chúng tôi tiếp tục tạo các tuyến đường PUT và DELETE.
Tuyến đường PUT
Tuyến PUT gần giống như tuyến POST. Chúng tôi sẽ chỉ định id cho đối tượng sẽ được cập nhật / tạo. Tạo tuyến đường theo cách sau.
router.put('/:id', function(req, res){
//Check if all fields are provided and are valid:
if(!req.body.name ||
!req.body.year.toString().match(/^[0-9]{4}$/g) ||
!req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
!req.params.id.toString().match(/^[0-9]{3,}$/g)){
res.status(400);
res.json({message: "Bad Request"});
} else {
//Gets us the index of movie with given id.
var updateIndex = movies.map(function(movie){
return movie.id;
}).indexOf(parseInt(req.params.id));
if(updateIndex === -1){
//Movie not found, create new
movies.push({
id: req.params.id,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
});
res.json({message: "New movie created.", location: "/movies/" + req.params.id});
} else {
//Update existing movie
movies[updateIndex] = {
id: req.params.id,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
};
res.json({message: "Movie id " + req.params.id + " updated.",
location: "/movies/" + req.params.id});
}
}
});
Tuyến đường này sẽ thực hiện chức năng được chỉ định trong bảng trên. Nó sẽ cập nhật đối tượng với các chi tiết mới nếu nó tồn tại. Nếu nó không tồn tại, nó sẽ tạo một đối tượng mới. Để kiểm tra tuyến đường, hãy sử dụng lệnh curl sau đây. Điều này sẽ cập nhật một bộ phim hiện có. Để tạo Phim mới, chỉ cần thay đổi id thành id không tồn tại.
curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5"
http://localhost:3000/movies/101
Response
{"message":"Movie id 101 updated.","location":"/movies/101"}
XÓA tuyến đường
Sử dụng mã sau để tạo một lộ trình xóa. -
router.delete('/:id', function(req, res){
var removeIndex = movies.map(function(movie){
return movie.id;
}).indexOf(req.params.id); //Gets us the index of movie with given id.
if(removeIndex === -1){
res.json({message: "Not found"});
} else {
movies.splice(removeIndex, 1);
res.send({message: "Movie id " + req.params.id + " removed."});
}
});
Kiểm tra tuyến đường giống như cách chúng tôi kiểm tra các tuyến đường khác. Khi xóa thành công (ví dụ: id 105), bạn sẽ nhận được kết quả sau:
{message: "Movie id 105 removed."}
Cuối cùng, movies.js tệp sẽ giống như sau.
var express = require('express');
var router = express.Router();
var movies = [
{id: 101, name: "Fight Club", year: 1999, rating: 8.1},
{id: 102, name: "Inception", year: 2010, rating: 8.7},
{id: 103, name: "The Dark Knight", year: 2008, rating: 9},
{id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];
router.get('/:id([0-9]{3,})', function(req, res){
var currMovie = movies.filter(function(movie){
if(movie.id == req.params.id){
return true;
}
});
if(currMovie.length == 1){
res.json(currMovie[0])
} else {
res.status(404); //Set status to 404 as movie was not found
res.json({message: "Not Found"});
}
});
router.post('/', function(req, res){
//Check if all fields are provided and are valid:
if(!req.body.name ||
!req.body.year.toString().match(/^[0-9]{4}$/g) ||
!req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
res.status(400);
res.json({message: "Bad Request"});
} else {
var newId = movies[movies.length-1].id+1;
movies.push({
id: newId,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
});
res.json({message: "New movie created.", location: "/movies/" + newId});
}
});
router.put('/:id', function(req, res) {
//Check if all fields are provided and are valid:
if(!req.body.name ||
!req.body.year.toString().match(/^[0-9]{4}$/g) ||
!req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
!req.params.id.toString().match(/^[0-9]{3,}$/g)){
res.status(400);
res.json({message: "Bad Request"});
} else {
//Gets us the index of movie with given id.
var updateIndex = movies.map(function(movie){
return movie.id;
}).indexOf(parseInt(req.params.id));
if(updateIndex === -1){
//Movie not found, create new
movies.push({
id: req.params.id,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
});
res.json({
message: "New movie created.", location: "/movies/" + req.params.id});
} else {
//Update existing movie
movies[updateIndex] = {
id: req.params.id,
name: req.body.name,
year: req.body.year,
rating: req.body.rating
};
res.json({message: "Movie id " + req.params.id + " updated.",
location: "/movies/" + req.params.id});
}
}
});
router.delete('/:id', function(req, res){
var removeIndex = movies.map(function(movie){
return movie.id;
}).indexOf(req.params.id); //Gets us the index of movie with given id.
if(removeIndex === -1){
res.json({message: "Not found"});
} else {
movies.splice(removeIndex, 1);
res.send({message: "Movie id " + req.params.id + " removed."});
}
});
module.exports = router;
Điều này hoàn thành API REST của chúng tôi. Giờ đây, bạn có thể tạo các ứng dụng phức tạp hơn nhiều bằng cách sử dụng kiểu kiến trúc đơn giản này và Express.