Feathers.js là gì? Cách Dùng Feathers.js Cho Application Server

feather.js cho API Restful Application
Trong bài viết này, ta sẽ tìm hiểu cách xây dựng máy chủ API RESTful trong Node.js bằng Feathers.js.

Application server là gì?

API Server (máy chủ API), còn được gọi là Máy chủ ứng dụng, là chương trình cung cấp dữ liệu cho các ứng dụng front-end. Máy chủ API giúp xử lý logic ở back end và cung cấp quyền truy cập hạn chế vào cơ sở dữ liệu của tổ chức. Máy chủ API không chỉ ngăn chặn những người không được phép truy cập dữ liệu; mà cũng có thể hạn chế người dùng đăng nhập truy cập hoặc thay đổi dữ liệu nếu họ không có quyền hạn này.
Mỗi ứng dụng bạn xây dựng sẽ cung cấp một dịch vụ (service) gì đó cho người dùng cuối (end user). Để làm được điều đó, ứng dụng của bạn sẽ cần dữ liệu để xử lý. Bạn có thể sử dụng remote API (API từ xa) để tạo dịch vụ mới. Tuy nhiên, đối với hầu hết các ứng dụng, bạn sẽ cần quản lý kho dữ liệu của riêng mình. Phổ biến nhất là sử dụng các dịch vụ lưu trữ dữ liệu trực tuyến như Firebase. Bằng cách này, bạn không phải quá mất thời gian đi vào chi tiết khi chạy một máy chủ cơ sở dữ liệu phân tán. Tuy nhiên, nhu cầu dự án đôi khi buộc bạn phải dùng một hệ thống quản lý cơ sở dữ liệu nội bộ đầy đủ, như MongoDB hoặc Oracle. Đồng thời, để ứng dụng front-end của bạn truy cập dữ liệu được lưu trữ trong cơ sở dữ liệu, như vậy, bạn sẽ cần một máy chủ ứng dụng (application server) nằm giữa cơ sở dữ liệu và ứng dụng front-end.
architecture
Như được minh họa trong sơ đồ trên, công việc của một máy chủ ứng dụng là truy cập dữ liệu từ cơ sở dữ liệu bằng các lệnh SQL hoặc NoQuery và chuyển đổi thành định dạng mà các ứng dụng front-end (client browser) có thể hiểu - chẳng hạn như JSON. Ngoài ra, máy chủ ứng dụng có thể sử dụng các giao thức bảo mật khác nhau - chẳng hạn như mã hóa HTTPS và token authorization - để đảm bảo rằng giao tiếp giữa cơ sở dữ liệu và ứng dụng client được an toàn và bảo mật. Một lợi thế chính của việc sử dụng kiến trúc như vậy là với cùng một máy chủ ứng dụng, bạn có thể triển khai các ứng dụng nhắm đến các nền tảng khác nhau - máy tính để bàn, thiết bị di động, web, v.v. . Bạn cũng rất dễ dàng mở rộng quy mô ứng dụng theo chiều ngang nhằm phục vụ người dùng hiệu quả hơn với thời gian phản hồi nhanh hơn.
Chúng ta sẽ xây dựng một máy chủ API đơn giản và vận dụng các tính năng khác nhau mà Feathers cung cấp.

Feather là gì?

Feathers là một web-framework để xây dựng ứng dụng và REST API thời gian thực bằng cách sử dụng JavaScript hoặc TypeScript với Node.JS, React Native và trình duyệt.
Feathers hoạt động với bất kỳ backend nào hỗ trợ nhiều cơ sở dữ liệu và với bất kỳ công nghệ frontend nào như React, VueJS, Angular, Android hoặc iOS.
Với Feather, bạn có thể xây dựng prototype trong vài phút và ứng dụng dùng được ngay chỉ trong vài ngày.

Chuẩn bị trước khi dùng Feather

Trước khi bạn bắt đầu làm theo hướng dẫn này, bạn sẽ cần phải có nền tảng tốt với các kiến thức sau (nếu bạn nào có yêu cầu thì mình sẽ viết tiếp các hướng dẫn này nhé):
  • ES6 JavaScript
  • Xây dựng Express apps
  • Xây dựng RESTful APIs với Express
Feathers được xây dựng trên nền Express, một web framework tối giản cho Node.js. Nếu đã quen thuộc với RESTful API, bạn sẽ nhận ra rằng việc xây dựng các RESTful API chỉ bằng Express rất khó khăn. Với Feathers, hầu hết các công việc lặp đi lặp lại đã được thực hiện sẵn giúp bạn. Bạn chỉ cần tập trung vào cấu hình và tùy chỉnh code. Hãy cùng đi sâu vào code và tìm hiểu cách thức hoạt động của web framework này.

Tạo Project với Feather

npm install -g @feathersjs/cli
Để bắt đầu với Feathers, bạn sẽ cần cài đặt ứng dụng dòng lệnh theo cấp global:
Tiếp theo, tạo một dự án API mới bằng các lệnh bên dưới:
mkdir contacts-api
cd contacts-api
feathers generate app
Dưới đây là các tùy chọn tôi đã chọn. Bạt có thể tùy ý chọn bất kỳ testing framework nào. Thật không may, testing không phải trọng tâm của bài viết này, nên ta sẽ không đào sâu ở đây. Vì tác giả thích sự đơn giản, nên ta hãy dùng Jest nhé.
Creating a Feathers app in the command line
Sau khi cài đặt hoàn tất, bạn có thể mở trình soạn thảo code yêu thích của mình để xem file của dự án.
Project structure, as seen in a code editor
Nếu bạn đã thông tạo các thao tác về Express được liệt kê trong phần "chuẩn bị", chắc bị cũng không xa lạ với đoạn code đầu ra. Dưới đây sẽ tóm tắt nhanh các thư mục và tập tin.
  • config/ - Chứa các file cấu hình cho ứng dụng. File production.json sẽ viết đè default.json khi làm việc trong chế độ production với setting NODE_ENV=production.
  • node_modules/ Generator giúp cài đặt các thành phần cần thiết (Dependencies) cho project bằng npm, hay yarn. các dependency này cũng sẽ được thêm vào package.json
  • public/ chứa các trường tĩnh cần được serve. Một favicon mẫu và index.html (sẽ xuất hiện khi đến trực tiếp server URL) cũng có trong này.
  • src/ chứa code server Feather.
    • hooks/ chứa hooks tùy chỉnh
    • services/ chứa services tùy chỉnh
    • middleware/ chứa Express middleware bất kỳ
    • models/ chứa file database model
    • app.js cấu hình cho ứng dụng Feathers application
    • app.hooks.js registers hooks áp dụng cho mỗi service
    • authentication.js thiết lập hệ thống xác thực cho Feathers
    • channels.js  Thiết lập event channels của Feathers
    • index.js loads và starts ứng dụng
  • test/ chứa file test, hook và service cho app
    • services/ chứa test service
      • users.test.js chứa test cơ bản cho service users
    • app.test.js tests xem index page có xuất hiện không, và test lỗi 404 cho trang HTML và JSON
  • .editorconfig là thiết lập EditorConfig giúp developers xác lập và duy trì cách code nhất quán giữa những editor và IDE khác nhau.
  • .eslintrc.json chứa mặc định lint code với ESLint.
  • .gitignore chỉ định intentionally untracked files mà gitGitHub và các project tương tự khác ignore.
  • package.json chứ thông tin về project NodeJS như tên và dependency.
  • README.md chứa hướng dẫn cài đặt và sử dụng
Dừng quá quan tâm đến mỗi tập tin làm gì ngay bây giờ. Bạn sẽ hiểu cách chúng làm việc khi đi sâu vào trong hướng dẫn này. Hiện tại, hãy chắc chắn rằng test đang hoạt động.

Mình cùng "Lint" Code

Để đảm bảo dự án của chúng ta tuân thủ các quy tắc ESLint xác định, chỉ cần chạy lệnh npm test. Nếu bạn sử dụng nền tảng Unix hoặc Linux, thì nó sẽ chạy tốt. Nếu bạn sử dụng Windows, có vài thức cần điều chỉnh để test chạy thành công.
Đầu tiên, đi đến package.json và xem phần script. Thay đổi dòng kiểm tra này:
"scripts": {
  "test": "npm run eslint && SET NODE_ENV= npm run jest",
},
Tiếp theo, nếu bạn đã cài đặt Prettier trong Visual Studio Code, bạn sẽ cần thay đổi cài đặt single quote thành true trong tab Workspace settings:
{
  "prettier.singleQuote": true
}
Cuối cùng, hãy đảm bảo rằng, khi bạn tạo hoặc chỉnh sửa bất kỳ tệp nào, dòng kết thúc là LF. Nếu bạn sử dụng Visual Studio Code hoặc trình chỉnh sửa tương tự, bạn có thể kiểm tra style của dòng kết thúc hiện tại trên thanh trạng thái. Nếu bạn thấy CRLF, hãy đổi thành LF. Thực hiện những thay đổi đó sẽ giúp bạn vượt qua lint test.
Hãy cùng xem xét cách chúng ta có thể tạo giao diện CRUD RESTful.

Tạo Service

Xây dựng giao diện API CRUD đầy đủ trong Express đòi hỏi một chút công sức. Còn trong Feathers, tất cả những gì bạn phải làm là thực thi một lệnh duy nhất, trả lời một vài câu hỏi và code sẽ tạo sẵn cho bạn:
$ feathers generate service
? What kind of service is it? NeDB
? What is the name of the service? contacts
? Which path should the service be registered on? /contacts
? What is the database connection string? nedb://../data
    force config\default.json
   create src\services\contacts\contacts.service.js
    force src\services\index.js
   create src\models\contacts.model.js
   create src\services\contacts\contacts.hooks.js
   create test\services\contacts.test.js
Chúng ta sẽ sử dụng database NeDB cho hướng dẫn này. Feathers không hỗ trợ các database SQL như MySQL hay NoQuery như MongoDB. Tuy nhiên, việc cài đặt hệ thống cơ sở dữ liệu, dù là trên máy của bạn hoặc trên máy chủ đám mây, đòi hỏi một lượng thời gian nhất định để định cấu hình hệ thống. Mặt khác, NeDB là in-memory database bằng 100% JavaScript và hỗ trợ một tập hợp API MongoDB. Không cần cấu hình thêm; bạn chỉ việc cài đặt thôi. Đây là một cơ sở dữ liệu tuyệt vời để tạo prototype và test các ứng dụng mới.
Hãy để xem nhanh một số tệp đã được tạo bằng lệnh này:
  • services/contacts/contact.service.js. Đây là service Feathers cung cấp endpoints của CRUD API cho /contacts. Nhỏ xíu đúng không? Nhỏ như vậy là do Feathers đã tối ưu sẵn cho chúng ta. Ta không cần phải phí công viết mã CRUD soạn sẵn.
  • services/contacts/contact.hooks.js. Đây là nơi chúng ta sẽ tùy chỉnh cách hoạt động của logic CRUD. Chúng ta có phần before, tại đây ta có thể kiểm tra hoặc thay đổi dữ liệu trước khi Feathers đọc hoặc ghi vào cơ sở dữ liệu. Còn có phần after, tại đây chúng ta có thể kiểm tra hoặc thay đổi kết quả từ cơ sở dữ liệu trước khi được gửi đến ứng dụng client. Chúng ta còn có thể làm nhiều thức khác như hạn chế quyền truy cập, xác thực dữ liệu, thực hiện các thao tác ghép nối và tính toán giá trị cho các trường hoặc cột bổ sung.
  • models/contacts.model.js. Đây là nơi chúng ta xác định mô hình và gán nó vào một bảng cơ sở dữ liệu. Ở đây tac cũng sẽ xác định schema dùng để xác thực các trường khi một bản ghi mới được chèn hoặc cập nhật. Đáng tiếc, NeDB hỗ trợ schemas. Tuy nhiên, bạn sẽ có ví dụ dưới đây về model kết nối với MongoDB, model hỗ trợ schema thông qua adapter mongoose:
"use strict";

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
require("mongoose-type-email");

const contactsSchema = new Schema({
  name: {
    first: { type: String, required: [true, "First Name is required"] },
    last: { type: String, required: false }
  },
  email: {
    type: mongoose.SchemaTypes.Email,
    required: [true, "Email is required"]
  },
  phone: {
    type: String,
    required: [true, "Phone is required"],
    validate: {
      validator: function(v) {
        return /^\+(?:[0-9] ?){6,14}[0-9]$/.test(v);
      },
      message: "{VALUE} is not a valid international phone number!"
    }
  },
  createdAt: { type: Date, default: Date.now },
  updatedAt: { type: Date, default: Date.now }
});

const contactsModel = mongoose.model("contacts", contactsSchema);

module.exports = contactsModel;
Mặc dụ vẫn còn hạn chế, NeDB vẫn là một cơ sở dữ liệu tuyệt vời để tạo prototype. Hầu hết các database NoSQL sẽ cho phép bạn gửi dữ liệu bằng cách sử dụng bất kỳ cấu trúc nào mà không phải xác định trước schema. Sau khi các yêu cầu của dự án đã được thỏa mãn, thì lúc đó mới nên implement schema. Khi đã có schema, Feathers sẽ thực hiện field validation cho bạn với các quy tắc bạn đã xác định. Bạn sẽ cần một cơ sở dữ liệu sẵn sàng hoạt động như MongoDB để có thể xác định schema. Lưu ý rằng việc cấu hình cho development database được xác định tại config/default.json:
"nedb": "../data"
Ở đây sẽ có thông tin đăng nhập của database. Chúng ta còn có một tệp cấu hình khác là config/production.json. Đây là cấu hình của production database được dùng khi bạn triển khai ứng dụng Feathers. Việc sử dụng cơ sở dữ liệu riêng biệt trong quá trình develop rất quan trọng. Nếu không, nguy cơ vô tình xóa hoặc làm hỏng dữ liệu hoạt động của business trên production database là rất cao.
Bây giờ ta đã có CRUD service để set up contacts, đến lúc dùng thử rồi. Bạn có thể khởi động máy chủ Feather bằng lệnh npm start. Lưu ý rằng máy chủ này không hỗ trợ hot reload. Vì vậy, sẽ cần phải khởi động lại mỗi khi bạn thay đổi code. Để tương tác với ứng dụng Feathers, chúng ta sẽ cần một API browser như Postman hoặc Insomnia. Bài viết sẽ sử dụng Insomnia trong hướng dẫn này.
Tạo GET request mới (nhấn Ctrl + N) và đặt tên là "List Contact". Trong phần URL, nhập http://localhost:3030/contacts. Khi nhấn nút Sendbutton, ta sẽ thấy:
Listing contact requests: the view in your code editor after hitting the Send button
Trống hoắc! Database của chúng ta đang trống không, hãy tạo contact mới bằng request Create Contact và nhập thông tin như dưới đay:
Form for creating the new contact
Nếu bạn quên đổi METHOD thành POST trong form trên, đổi lại sau cũng được. Hãy đổi method thành POST và thay đổi tab Body thành JSON. Copy đoạn dữ liệu sau vào tab JSON:
{
  "name": {
    "first": "Jack",
    "last": "Bauer"
  },
  "email": "jack@ctu.mail",
  "phone": "+1234567"
}
Khi nhấn nút Send, bạn sẽ thấy phản hồi như dưới. Để ý là một _id đã được tạo cho contact mới.
Response with new ID
Quay lại List Contacts và nhấn nút Send lần nữa. Ta sẽ có kết quả sau:
{
  "total": 1,
  "limit": 10,
  "skip": 0,
  "data": [
    {
      "name": {
        "first": "Jack",
        "last": "Bauer"
      },
      "email": "jack@ctu.mail",
      "phone": "+1234567",
      "_id": "ybnRxL6s2QEGhj4i"
    }
  ]
}
Quay trở lại Create Contact và đăng vài bản ghi mới:
{
  "name": {
    "first": "Chloe",
    "last": "O'Brian"
  },
  "email": "chloe@ctu.mail",
  "phone": "+1987654"
}
{
  "name": {
    "first": "Renee",
    "last": "Walker"
  },
  "email": "renee@fbi.mail",
  "phone": "+150505050"
}
Hãy thực hiện update. Để update, ta sẽ không dùng phương thức UPDATE HTTP. Phương thức này sẽ ghi đè hoàn toàn một bản ghi. Những gì ta muốn làm là chỉ là ghi đè lên một trường duy nhất, chứ không phải toàn bản ghi, như vậy ta sẽ sử dụng PATCH. Tạo request mới, rồi Update Contact như dưới đây:
Updating a contact
Trong trường URL, để vào http://localhost:3030/contacts/{_id}. Thay thế {_id} Bằng ID của bản ghi đầu tiên. Nhập đoạn dữ liệu sau vào tab JSON:
{
  "email": "jack.bauer@gmail.com"
}
Nhấn nút Send. Bạn sẽ thấy kết quả sau:
08-Patch-Jack-Email
Chú ý các trường còn lại vẫn giữ nguyên. Tiếp theo, chúng ta sẽ xóa một bản ghi (cái này thì dễ). Chỉ cần tạo request DELETE và đặt tên là Delete Contact. Trong trường URL, hãy dùng định dạng http://localhost:3030/contacts/{_id}. Giống trước đó, thay thế {_id} bằng ID của bản ghi bạn muốn xóa. Nhấn Send sẽ xóa bản ghi đó cho bạn. Bạn có thể xác nhận bằng cách chạy lại request List Contact.
Chúng ta vừa xác minh rằng tất cả các hoạt động CRUD đang chạy ổn định. Trong phần tiếp theo, ta sẽ học cách thiết lập xác thực.
[the_ad id="1445"]

Authentication - Xác thực

Ngay bây giờ, endpoint của API /contacts đang không được bảo vệ. Nếu chúng ta deploy ứng dụng lên máy chủ cloud, bất kỳ ai có URL đều có thể truy cập và thao túng các bản ghi của chúng ta. Để hạn chế quyền truy cập, ta sẽ phải thiết lập authencation. Để triển khai authencation, hãy sử dụng JSON Web Token bằng lệnh sau:
feathers generate authentication
Như bạn có thể thấy bên dưới, Feathers hỗ trợ nhiều cách xác thực người dùng khác nhau. Cách dễ nhất là tùy chọn “Local Username + Password”.
Authentication setup options in Feathers
Chọn các option dưới đây cho những câu hỏi còn lại.
Options for the remaining questions
Bạn có thể review các file vừa tạo bằng cùng lệnh đã thực thi:
authentication files
Bước kế tiếp là tạo user mới. Ta có thể dùng Insomnia hay công cụ API browser bất kỳ. Tạo request mới và đặt tên Create User:
Create User form
Trong tab JSON, gửi đi data sau:
{
  "email": "admin@example.com",
  "password": "secret"
}
Kết quả nhận được sẽ thế này:
User created
Giờ ta đã có user rồi. Hãy confirm bằng cách tạo request List Users và send URL http://localhost:3030/users. Thật không may, ta sẽ nhận được response là:
List Users Failed
Chúng tôi cần được xác thực để truy cập dữ liệu này. Vì chúng ta vẫn chưng có ứng dụng front-end mà để đăng nhập, nên ta sẽ tiếp tục sử dụng trình duyệt API. Tạo một yêu cầu mới và đặt tên là “Get JWT Token”. Điền vào form như minh họa dưới đây:
Get JWT Token Form
Yêu cầu này sử dụng phương thức POST. Trong tab JSON, copy dữ liệu sau:
{
  "strategy": "local",
  "email": "admin@example.com",
  "password": "secret"
}
Bạn sẽ nhận được phản hồi sau khi nhấn nút send:
Access Token generated
Copy the token code (without the double quotation marks). Go to List Usersrequest page, select the Auth tab and pick Bearer. Paste this token code in the TOKEN field.
Sao chép token code (không có dấu ngoặc kép). Chuyển đến trang request List Users, chọn tab Auth và chọn Bearer. Dán mã token này vào trường TOKEN.
List users with token
Khi bạn nhấn nút Gửi, bạn sẽ nhận được một danh sách người dùng. Lưu ý rằng hệ thống xác thực của chúng ta vẫn chưa hoàn toàn an toàn. Bất cứ ai với URL endpoint /users đều có thể tạo tài khoản mới và có quyền truy cập vào hệ thống. Để ngăn chặn việc tạo trái phép các tài khoản mới, chúng ta cũng cần hạn chế endpoint này. Mở tệp services/users/users.hooks.js và update đoạn mã sau:
module.exports = {
  before: {
    //...
    create: [ hashPassword(), authenticate('jwt') ],
    //...
Điều này sẽ đảm bảo chỉ người dùng được xác thực mới có thể tạo tài khoản mới. Bước tiếp theo là bảo vệ enpoint /contacts. Chỉ cần mở tệp services/contacts/contacts.hooks.js và cập nhật tương ứng:
const { authenticate } = require('@feathersjs/authentication').hooks;

module.exports = {
  before: {
    all: [authenticate('jwt')],
    //...
  },
Restart the Feathers server for the code changes to take effect. If you try running the List Contacts request, you’ll get the following response:
Khởi động lại máy chủ Feathers để thay đổi có hiệu lực. Nếu bạn thử chạy yêu cầu List Contacts, bạn sẽ nhận được phản hồi sau:
{
  "name": "NotAuthenticated",
  "message": "No auth token",
  "code": 401,
  "className": "not-authenticated",
  "data": {},
  "errors": {}
}
Để được xác thực, bạn sẽ cần thiết lập token Bearer giống như trước đây. Khi đã làm xong, bạn có thể gửi yêu cầu và sẽ nhận được contact list. Hãy lưu ý rằng token đã nhận được đó sẽ hết hạn sau một ngày. Để tăng độ hiệu quả,bạn nên dùng environment variables để dễ dàng cập nhật đồng loat các API variable. Khi xây dựng một ứng dụng front-end, bạn sẽ cần lưu trữ token này bên trong local storage, chứ đừng dung cofokie. Nếu không, ứng dụng của bạn sẽ "mỏng manh" hơn trước các cuộc tấn công CSRF. Kiểm tra tài liệu Feathers về bảo mật để tìm hiểu thêm về các rủi ro bảo mật khác mà bạn nên biết.
Bây giờ bạn đã thiết lập xác thực, bất kỳ service mới nào bạn tạo sau này sẽ cung cấp cho bạn tùy chọn bảo vệ endpoint mới. Bây giờ chúng ta hãy xem chủ đề cuối cùng cho hướng dẫn này trong phần tiếp theo.

Hooks

Hook (móc) là các hàm trung gian được gắn vào beforeafter hay errors của một service method. Chúng thường được sử dụng để xử lý những việc như đăng nhập, hạn chế quyền truy cập, bảo vệ các trường, gửi thông báo, v.v. Nếu bạn nhìn vào services/users/users.hooks.js, bạn có thể thấy một số hook Feathers đang hoạt động. Chúng ta sẽ tạo thử móc tùy chỉnh. Đầu tiên, dừng máy chủ và xóa bảng database data/contacts.db. Tiếp theo, tạo một hook mới bằng cách tạo lệnh sau:
feathers generate hooks
Sử dụng các tùy chọn sau để tạo process-contact cho hook tùy chỉnh:
Create contact process in Hook
Những gì ta muốn làm trong hook này là inject hai trường mới ngay trước khi yêu cầu Create Contact được xử lý.
  • createdBy: liên kết với người dùng được log in thông qua _id
  • createdOn: thêm ngày tạo
Mở file hooks/process-contact.js và update file này như sau:
module.exports = function(options = {}) {
  return async context => {
    return context;
  };
};
module.exports = function(options = {}) {
  return async context => {
    // Get authenticated user
    const user = context.params.user;

    //Extract Submitted Data
    const { data } = context;

    // Add new Fields
    context.data = {
      ...data, // Preserve submitted data
      createdBy: user._id,
      createdOn: new Date()
    };
    return context;
  };
};
Kế tiếp, tạo một hook khác, populate-user nối object user với record contact khi được yêu cầu. Làm theo hướng dẫn như screenshot dưới đây:
populate user hook
Mở file hooks/populate-user và thêm đoạn code sau:
// eslint-disable-next-line no-unused-vars
module.exports = function(options = {}) {
  return async context => {
    const { app, method, result, params } = context;

    // Ensure contacts is an array. If it's a single contact, wrap it into an array
    const contacts = method === "find" ? result.data : [result];

    // Fetch user object from each contact's createdBy
    await Promise.all(
      contacts.map(async contact => {
        contact.user = await app
          .service("users")
          .get(contact.createdBy, params);
      })
    );

    return context;
  };
};
Đọc comments để hiểu cách hoạt động của từng đoạn code. Bây giờ bạn có thể khởi động máy chủ. Tạo lại ba contact bằng cách sử dụng yêu cầu Create Contact. Đặt bearer token, nếu vẫn chưa có. Nếu không, bạn sẽ thấy lỗi authorization. Đây là phản hồi bạn sẽ nhận được khi tạo contact mới:
Created by with auth

Lời kết Về Feather.js

Hy vọng thông qua bài viết, bạn đã có thể xây dựng nhanh máy chủ API RESTful của riêng mình với Feather.js. Nếu muốn đào sâu hơn về project contacts-api,Chúng tôi khuyến khích bạn nên tạo một ứng dụng front-end bằng framework tùy thích. Build log-in screen và các trang CRUD cho endpoint /contacts và /users. Chúc bạn vui vẻ với thử thách nho nhỏ này nhé!
Theo Sitepoint

Nhận xét

Bài đăng phổ biến