Services是每個Feathers應(yīng)用的心臟。一個service就是一個簡單的JavaScript對象,它提供一個或多個find, get, create, update, remove 以及setup 的服務(wù)方法,并且可以像Express 中間件一樣使用 app.use('/path', serviceObject).
讓我們通過一個簡單的service和REST provider來創(chuàng)建一個Feathers應(yīng)用:
// app.js
const feathers = require('feathers');
const rest = require('feathers-rest');
const app = feathers();
app.configure(rest());
app.use('/todos', {
get(id, params) {
return Promise.resolve({
id,
params,
description: `You have to do ${id}!`
});
}
});
app.listen(3030);
接著我們來運行它
$ npm install feathers feathers-rest
$ node app.js
我們通過瀏覽器打開localhost:3030/todos/dishes后,你將看到如下結(jié)果:
{
"id": "dishes",
"description": "You have to do dishes!",
"params": {
"provider": "rest",
"query": {}
}
}
加一個參數(shù)試試,就像這樣localhost:3030/todos/dishes?name=David,我們會看到如下的結(jié)果:
{
"id": "dishes",
"description": "You have to do dishes!",
"params": {
"provider": "rest",
"query": {
"name": "David"
}
}
}
引用services
當我們通過app.use('/my-service', myService)注冊service的時候, Feathers為myService這個對象創(chuàng)建了一個淺拷貝并為擴充了它的功能. 這意味著這個服務(wù)繼承了Feathers的方法(real-time events, hooks......). 我們可以使用app.service來引用這個服務(wù):
const todos = app.service('todos');
// 我們也可以給它加上 前/后斜杠
const todos = app.service('/todos/');
// 通過如下方法使用這個服務(wù)
todos.get('laundry').then(todo => console.log(todo.description));
重要: 原始的service對象并不會被改變,并且永遠不會繼承Feathers的功能。
Service 方法
完整的service方法列表如下:
const myService = {
find(params [, callback]) {},
get(id, params [, callback]) {},
create(data, params [, callback]) {},
update(id, data, params [, callback]) {},
patch(id, data, params [, callback]) {},
remove(id, params [, callback]) {},
setup(app, path) {}
}
app.use('/my-service', myService);
使用ES6 class(類)方式定義如下:
'use strict';
class MyService {
find(params [, callback]) {}
get(id, params [, callback]) {}
create(data, params [, callback]) {}
update(id, data, params [, callback]) {}
patch(id, data, params [, callback]) {}
remove(id, params [, callback]) {}
setup(app, path) {}
}
app.use('/my-service', new MyService());
Service方法需要返回一個Promise對象并且具有下列參數(shù):
-
id資源標識符,每個資源都是擁有唯一的ID的數(shù)據(jù)。 -
data指代資源數(shù)據(jù)。 -
params可以包含任何額外的參數(shù), 例如用戶驗證.params.query包含來自客戶端的查詢參數(shù) (參考 REST providers 和 real-time providers)。 -
callback是一個可選的回掉函數(shù),可以被一個 Promise 替代. 它是一個節(jié)點式回調(diào)函數(shù),該函數(shù)遵循function(error, result) {}。
這些方法基本上映射了CRUD接口:
-
find(params [, callback])檢索來自服務(wù)端的所有資源,Provider的參數(shù)將通過params.query進行傳遞。 -
get(id, params [, callback])通過指定的id從服務(wù)器中檢索單一資源。 -
create(data, params [, callback])用data創(chuàng)建一個新的資源。這個方法將返回一個包含新創(chuàng)建的數(shù)據(jù)的Promise。data也可能是一個數(shù)組,它將創(chuàng)建并返回一個資源列表. -
update(id, data, params [, callback])用新的data替換原來標識為id資源。這個方法會返回一個包含著完整的更新資源數(shù)據(jù)的Promise。當更新多條數(shù)據(jù)時id也可以為空null. -
patch(id, data, params [, callback])將新的data與標識為id的現(xiàn)有資源合并為新的數(shù)據(jù)。 合并多個資源時id可以為空null。這個方法會返回一個包含著完整的更新資源數(shù)據(jù)的Promise。Implementpatchadditionally toupdateif you want to separate between partial and full updates and support thePATCHHTTP method. -
remove(id, params [, callback])通過id標識刪除資源數(shù)據(jù). 這個方法將返回一個包含被刪除資源的Promise. 刪除多個資源時id可以為空null。
setup 方法
setup(app, path) 通過一個Feathers應(yīng)用的實例和一個已注冊的路徑來初始化service。使用setup 是用來連接服務(wù)器的好方法:
// app.js
'use strict';
const feathers = require('feathers');
const rest = require('feathers-rest');
class TodoService {
get(id, params) {
return Promise.resolve({
id,
description: `You have to ${id}!`
});
}
}
class MyService {
setup(app) {
this.app = app;
}
get(name, params) {
const todos = this.app.service('todos');
return todos.get('take out trash')
.then(todo => {
return { name, todo };
});
}
}
const app = feathers()
.configure(rest())
.use('/todos', new TodoService())
.use('/my-service', new MyService())
app.listen(8000);
你可以通過訪問localhost:8000/my-service/test這個地址來查看以上代碼的結(jié)果。
事件(Events)
Any registered service will automatically turn into an event emitter that emits events when a resource has changed,
當資源發(fā)生改變時,任何已注冊的服務(wù)會自動轉(zhuǎn)變?yōu)橐粋€事件發(fā)射器來執(zhí)行發(fā)送事件。這個改變包含 create, update, patch 或這是 remove service call returned successfully. 如果你想了解更多關(guān)于事件(events)的信息, 請訪問如下章節(jié) real-time events.