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