node-qi

0.6.3 • Public • Published

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 listener qi 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.

Dependencies (26)

Dev Dependencies (9)

Package Sidebar

Install

npm i node-qi

Weekly Downloads

1

Version

0.6.3

License

MIT

Last publish

Collaborators

  • hfcorriez