icon picker
Feathers

$ npm install -g @feathersjs/cli
$ mkdir feathers-chat
$ cd feathers-chat
$ feathers generate app
Chọn JS or TS
chọn tên cho project - enter để lấy tên thư mục
description cho app
tên folder để chưa file source, mặc định là src
chọn package manager (npm or yarn)
chọn dạng kết nối → chat → REST với REaltime via socket
TEsting framework ? Mocha + assert hay Jest
App có authentication không
dạng code convension (ESlint)
cách authentication (Oauth, local, ...)
name của entity
→ chọn db mongo
đường dẫn
mongodb+srv://admin:admin@cluster0-0ssna.mongodb.net/feathers?retryWrites=true&w=majority
$ npm start

Cấu trúc thư mục

config/
default.json chứa các tùy chỉnh cơ bản của webservice
production.json chưa các tùy chỉnh khi ứng dụng ở chế độ production NODE_ENV = production
public/ chứa các static file, index.html để hiển thị khi vào trang chính của server
src/
hooks/ chưa các hooks của feather
services/ chưa các service do feather generate ra
users/ là service được tạo ra để đăng kí và phân quyền user
users.class.js là service class
users.hook.js là các hook của service này
users.service.js dùng để đăng kí service này trên trang ứng dụng của feathers
middleware/
models/ chưa các file định nghĩa model trong db
users.model.js setup user collection
app.js
app.hooks.js đăng kí các hook dùng cho các service
authentication.js , setup phần phân quyên cho ứng dung
channels.js setup event channels dành cho socket ..
index.js load và start app
test/
services/ services test
users.test.js các test cơ bản của user service
app.test.js test các trường hợp cơ bản như index page hay 404
authentication.test.js test cho phần phân quyền

Services

Service là một object hoặc class thực hiện implements một method nào đó. tạo một interface để kết nối với các dữ liệu như
đọc hoặc ghi vào db
thao tác filesyss\
gọi API khác
gọi các services khác như
gửi email
thực hiên payment
location, weather
Các service method là các hàm CRUD mà một service có thể có. bao gồm
find → find toàn bộ data hoặc một phần thõa query
get → get 1 data bằng id
create → tạo data mới
update → update bằng cách thay thế hoàn toàn cái mới
patch → update 1 phần bằng cách merger với cái đã có
remove →
class MyService {
async find(params) {}
async get(id, params) {}
async create(data, params) {}
async update(id, data, params) {}
async patch(id, data, params) {}
async remove(id, params) {}
}

app.use('/my-service', new MyService());
id → unique identifier of data
data → data được send bởi user dùng cho create, update, patch
params (optional) → các params thêm như là để auth or query
VD REST API
service.find({ query: {} })
GET
/messages
1
service.find({ query: { unread: true } })
GET
/messages?unread=true
2
service.get(1)
GET
/messages/1
3
service.create(body)
POST
/messages
4
service.update(1, body)
PUT
/messages/1
5
service.patch(1, body)
PATCH
/messages/1
6
service.remove(1)
DELETE
/messages/1
There are no rows in this table
6
Count
Đăng kí service với app
app.use(’messages’, new MessageService());
Để nhận service object và sử dụng các service method
const messageService = app.service('messages');
const messages = await messageService.find();
Service Events
Service sau khi được đăng kí với app sẽ thành một NodeJS EventEmitter sẽ gửi event và data . Event sẽ được lắng nghe bằng cách
app.service(’messages’).on(’eventName’, data => {});

Tạo thêm serviec

feathers generate service
kind of service → mongoose luôn
name of sservice→ messages
path: → /messages
required auth ? → yes

Config lại service User thêm avatar

chỉnh lại các service ta vào ....class.js
ta chỉnh service user.class.js
...

Hook

Ta thấy ta có thể thêm các hàm process vào service để tủy chỉnh ứng dụng
Nhưng có nhiều trường hợp, ta cần một hàm chạy trong nhiều service
Ví dụ authen tất cả các service xem user có quyền sử dụng hay không
Hoặc thêm trường thơief gian vào tất cả dữ liệu ta thêm
Nếu tùy chỉnh bằng các hàm trong services ta sẽ phải làm đi làm làm công đoạn thêm hàm với mỗi service
→ HOOK
hook là một middlerware function được đăng kí vào các giai đoạn before, after, error của các service methods/
ta có thể gán nhiều hook cho một method để tạo nên một flow phức tạp
Hook thường được dùng cho các việc như là validation, auth, logs, sinh các entities, send notification và nhiều cái nữa
Hook function - hàm hook
là func dùng hook context là param và trả về context đó( đã được chỉnh sửa) hoặc không trả về gì.
Hook được chạy theo thứ tự nó được đăng kí. Nếu một hook quăng lỗi → tất cả các hook khác và service có hook đó sẽ skip và sẽ tới phiền errors.
Pattern cho việc tạo hook dễ tái sử dụng là dùng một wrapper function nhận các option và trả về một hook
const hookName => options => async context => { ... return context }

hook context là object chưa thông tin về hàm service gọi hook

2 loại context là read only và wriable
READ-ONLY
context.app - The Feathers application object. This can be used to e.g. call other services
context.service - The service this hook is currently running on
context.path - The path (name) of the service
context.method - The service method name
context.type - The hook type (before, after or error)
WRIABLE
context.params - The service method call params. For external calls, params usually contains:
context.params.query - The query (e.g. query string for REST) for the service call
context.params.provider - The name of the transport (which we will look at in the next chapter) the call has been made through. Usually rest, socketio, primus. Will be undefined for internal calls.
context.id - The id for a get, remove, update and patch service method call
context.data - The data sent by the user in a create, update and patch service method call
context.error - The error that was thrown (in error hooks)
context.result - The result of the service method call (in after hooks)

register hook

để đăng kí hook ta đăng kí trong file .hooks.js của các service

Khi nào dùng hook, khi nào extended service khi nào custom service

Hook khi
chức năng được dùng nhiều hơn một nơi (validation, permission)
Đó không phải chức năng chính của service và service có thể hoạt động không có nó (gửi email sau khi create user)
Extend service khi
chức năng chỉ dùng trong service này
service không thể hoạt động thiếu nó
Custom service khi
nhiều service combined với nhau (report)
Service làm nhiều thao tác khác chứ không chỉ nói chuyện với db (call another API, sensor)

Authentication

POST /users → create user
{
“email”:”aquarius.superstar@gmail.com”,
“password”:”quang123”
}
→ vào db thấy tạo ra được user
Authen POST /authentication → READ
{
"strategy":"local",
"email":"aquarius.superstar@gmail.com",
"password":"quang123"
}
→ có được token → gửi vào postman: Authorization: Bearer <Token>

Gắn auth with github

Đăng kí app với github
call back url phải là
http://localhost:3030/oauth/github/callback
ta sẽ lấy được ClientId và client secret
bỏ vào file config/default.json phần authentication
{
"authentication": {
"oauth": {
"redirect": "/",
"github": {
"key": "<Client ID>",
"secret": "<Client Secret>"
}
},
// Other authentication configuration is here
// ...
}
}
Update src/authentication.sj
const { AuthenticationService, JWTStrategy } = require('@feathersjs/authentication');
const { LocalStrategy } = require('@feathersjs/authentication-local');
const { expressOauth, OAuthStrategy } = require('@feathersjs/authentication-oauth');

class GitHubStrategy extends OAuthStrategy {
async getEntityData(profile) {
const baseData = await super.getEntityData(profile);

return {
...baseData,
// You can also set the display name to profile.name
name: profile.login,
// The GitHub profile image
avatar: profile.avatar_url,
// The user email address (if available)
email: profile.email
};
}
}

module.exports = app => {
const authentication = new AuthenticationService(app);

authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('github', new GitHubStrategy());

app.use('/authentication', authentication);
app.configure(expressOauth());
};
Để login với github ta chỉ cần visit localhost:3030/oauth/github



Tạo user → tạo 1 account kèm theo
Tạo 1 OTP → Tìm user_id có tồn tại chưa → có thì update new OTP, chưa thì create → gửi mail
Tạo 1 transaction → có OTP kèm theo, Kiểm tra → ktra ok tạo transaction.
Create User
Create Account
Account have user_id
Create OTP
OTP have User Information
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.