node-qi
v0.6.3
Published
`Function-driven elegant event cross-language framework`
Downloads
1
Readme
Intro
Function-driven elegant event cross-language framework
Design
Purpose
- Serverless.
- Focus on frontend.
Principle
- Everything base
Event
- Everything is
Function
- Everything through
IO
TODO
- [ ] 函数调用机制,考虑更好的中间件?
0.7
- [ ] 自定义 Listener
- [ ] 插件机制
- [ ] Dashboard
0.8
- [ ] 函数分布式调用
Structures
Application Structure
- app
+ posts
- posts.js
- function.yml
+ login
- login.js
- function.yml
+ logout
- logout.js
- function.yml
+ resetPassword
- function.yml
- qi.<ENV>.yml
- qi.yml
Runtime Structure (TODO)
App ID
is defined by md5(<Machine Name>:<QI Directory>)
or user defined --name
- [Home Diretory]
- .qi
- apps
- [App ID].json
- logs
- [App ID].error.log
Design
<Event Listeners>
HTTP (WS) CRON MQTT Queue EMAIL
| | | | |
Server Timer Subscriber Worker Postfix
↘ | | | ↙
↘ ↓ ↙ [Event Input]
---------- Dispatcher -----------
| |
| ↓ | ← Error Event
| |
| Match Function | ↑
| |
| ↓ [Services] | |
| |
| Invoke Function | |
| |
| ↓ | → Error
| |
-----------------------------------
| [Event Output]
↙ ↙ ↓ ↘ ↘
Render/Reply <No> MQTT Publish <No> <No>
<Event End>
Usage
Create qi app
bin/qi new [dir]
Create qi function
bin/qi create <function>
Start qi service
./bin/qi start [dir]
Config qi app
qi.xml
listeners:
http: # HTTP listener config
cookie:
keys: ["secret", "key"]
session:
type: cookie
key: sess
signed: true
websocket:
path: /ws
queue: # Queue listener config
host: localhost
queue: default # Queue name for process
concurrency: 1 # Queue process concurrency
mqtt: &mqttTestConfig
url: mqtt://localhost:1883
username: username
password: password
keepalive: 1
connectTimeout: 1000
settings: # Services config for functions usage
db: # Service instance name
url: 'mongodb://localhost:27017' # Service config
queue: # Service name
queue: default # Use queue name
host: localhost
mqtt: *mqttTestConfig
settings:
<dirName>: # Conver the function settings by dir name
<key>: <value>
# TODO: implements
plugins:
auth: plugin_auth
Write "events" function
events/events.js
:
event
is the data base on listenerqi
qi includes services and native params: function, event, invoke(function, event, qi)
exports.show = function *(event, qi, next) {
return {
body: {
event: event
}
}
}
events/function.yml
:
functions:
show: # Function name
events: # All events for function
http: # Event name
method: get
path: /events
cors: true # Cors. not implements.
stacks:
- common.checkPlatform
- common.checkIP
settings:
<key>: <value>
Invoke the function
./bin/qi invoke events.show
Context
Context is qi
Events
HTTP / WEBSOCKET
HTTP Config
listeners:
http:
# Cookie config
cookie:
keys: ["secret", "key"]
# Session config
session:
type: "cookie"
key: "sess"
signed: true
// How many process to start
process:
instances: 2
HTTP Event Match
http
match:
events:
- type: http
method: get
path: /index/home
events:
http: /index/home
HTTP Input
{
"type": "http",
"method": "get",
"path": "/users",
"url": "http://localhost/users",
"secure": false,
"origin": "http://localhost",
"host": "locahost:3000",
"domain": "localhost",
"ip": "127.0.0.1",
"ips": [],
"query": {
"a": "b"
},
"headers": {
"user-agent": "xxx"
},
"cookies": {
"uid": "xxxx"
},
"sessions": {
"uid": "xxx"
},
"files": {
"file": {
"tmpPath": "/tmp/xxx",
"name": "xxx",
"size": 111
}
},
"body": {
"username": "xxx"
}
}
HTTP Output
http
output:
{
"status": 200,
"body": "OK",
"sessions": {
"uid": "xx"
},
"cookies": {
"sess": "xxx"
},
"redirect": "Redirect URL",
"file": "File to send to client",
"attachment": "File to download"
}
websocket
output:
return String
Queue
Queue Config
listeners:
queue:
name: "default" # Queue name to process
host: "localhost" # Redis host for queue
settings:
queue: # Service name
queue: 'default' # Use queue name
host: "localhost"
Queue Match Event
events:
- type: queue
name: default
Queue Input
{
"type": "queue",
"name": "default",
"<key>": "<value>"
}
Queue Output
return true/false
is enough.
Cron
Cron Config
listeners:
cron: true
Cron Match Event
events:
- type: cron
cron: "* * * * *"
events:
cron: "* * * * *"
Cron Input
{
"type": "cron",
"time": 12342134123
}
Cron Output
return true/false
is enough.
MQTT
MQTT Config
listeners:
mqtt:
url: mqtt://localhost:1883
username: username
password: password
keepalive: 1
connectTimeout: 1000
MQTT Match Event
events:
- type: mqtt
mqtt: default
topic: posts/a
MQTT Input
{
topic: "posts/a",
payload: "message"
}
MQTT Output
return true/false
is enough.