rapid api development examples for impress application server / node.js (jsfwdays 2014)

29
Rapid API development examples for Impress Application Server (Node.js) Timur Shemsedinov Research Institute of System Technologies (UA, Kiev), MetaSystems Inc. mailto:[email protected] https://github.com/tshemsedinov/impress http://habrahabr.ru/users/marcusaurelius/ https://www.npmjs.org/package/impress

Upload: timur-shemsedinov

Post on 09-May-2015

319 views

Category:

Software


2 download

DESCRIPTION

Application code and the server configuration examples with file-system access, RAM state, database access and parallel asynchronous processing of different resource types by stateful and stateless API requests.

TRANSCRIPT

Page 1: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Rapid API development examples for Impress Application Server (Node.js)

Timur ShemsedinovResearch Institute of System Technologies (UA, Kiev), MetaSystems Inc.

mailto:[email protected] https://github.com/tshemsedinov/impresshttp://habrahabr.ru/users/marcusaurelius/ https://www.npmjs.org/package/impress

Page 2: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Impress Application Server is:

• Scaling transparent to applications• Application isolation (memory configuration database)• Deployment or update code without restart• Highload serving static files from memory (gzip, js minification, etc.)• URL-rewriting using RegExp, with internal redirection or sending

external HTTP-requests (reverse proxying)• Virtual hosts with multi-domain support (e.g.: *.domain.com)• Executable code and static caching in RAM• TCP port multiplexing and demultiplexing between applications• Server-Sent Events and WebSocket support• Stateless API (REST) and stateful API (RPC) support with IP-sticky

and Cookie-sticky to associated processes and global state sync.• Many other features: sessions, rotating logging, IPC and ZeroMQ,

database access drivers, etc.

Page 3: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Rapid API development examples

General principles:• Request routing based on file system• Each handler in separate file, handler inherit/override mechanism• Handlers need not prepare request execution environment, such as

import/load libraries, establish db connections, build memory structures, etc., request will come to ready application environment and handler will contain just applied code

• Each application have own isolated context and in-memory state• Long and batch workers in separate threads (forking by Impress

Application Server into parallel processes)• Global cross-server interprocess communication based on system

IPC and ZeroMQ to translate events, synchronize state, use reactive approach and actor-pattern

Page 4: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

1. Simple JSON handler

/example/app/examples/simple/jsonPost.json/post.jsmodule.exports = function(client, callback) { client.context.data = { a: 1 }; callback();}---------------------------------------------------------------HTTP POST /example/app/examples/simple/jsonPost.json{ "a": 1}

Page 5: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

2. Simple AJAX handler with template

/examples/simple/ajaxTest.ajax/get.jsmodule.exports = function(client, callback) { client.context.data = { parameterName: client.query.parameterName, }; callback();}

---------------------------------------------------------------/examples/simple/ajaxTest.ajax/html.templateAJAX Request with parameter returning back in template<br>parameterName: @parameterName@

---------------------------------------------------------------HTTP GET/examples/simple/ajaxTest.ajax?parameterName=parameterValueAJAX Request with parameter returning back in template<br>parameterName: parameterValue

Page 6: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

3. Client-side example

/js/init.js$.post('/examples/simple/jsonPost.json', { parameterName: "paramaterValue" }, function(res) { console.log(res.valueLength); });---------------------------------------------------------------HTTP POST /example/app/examples/simple/jsonPost.json{ "status": 1, "parameterValue": "paramaterValue", "valueLength": 14, "requestCounter": 3}---------------------------------------------------------------Console:14

Page 7: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

4. File system access example

/examples/simple/fsAccess.json/get.jsmodule.exports = function(client, callback) { var filePath = client.hostDir+client.path+'/test.txt'; fs.readFile(filePath, 'utf8', function(error, data) { client.context.data = { fileContent: data, dataLength: data.length }; callback(); });}---------------------------------------------------------------HTTP GET /examples/simple/fsAccess.json{ "fileContent": "?Example text file", "dataLength": 18}

Page 8: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

5. HTTP-request from API handle example

/examples/simple/httpRequest.json/get.jsmodule.exports = function(client, callback) { var req = impress.http.request({ hostname: 'google.com', port: 80, path: '/', method: 'get' }, function(response) { var data = ''; response.on('data', function(chunk) {data=data+chunk;}); response.on('end', function() { client.context.data = data; callback(); }); } ); req.on('error', function(e) { client.context.data = "Can't get page"; callback(); }); req.end();}

Page 9: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

6. MongoDB (read) access example

/examples/mongodb/getData.json/get.jsmodule.exports = function(client, callback) { dbAlias.testCollection.find({}).toArray( function(err, nodes) { client.context.data = nodes; callback(); } );}

---------------------------------------------------------------HTTP GET mongodb/getData.json[ { "_id": "53547375894c3d3022000001" }]

Page 10: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

7. MongoDB write and metadata examples

/examples/mongodb/insertData.json/get.jsmodule.exports = function(client, callback) { dbAlias.testCollection.insert(client.query, function(err) { client.context.data = !err; callback(); });}---------------------------------------------------------------/examples/mongodb/getCollections.json/get.jsmodule.exports = function(client, callback) { dbImpress.connection.collections(function(err, collections) { var items = []; for (var i = 0; i < collections.length; i++) { items.push(collections[i].collectionName); } client.context.data = items; callback(); });}

Page 11: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

8. SQL-query (MySql) access example

/examples/mysql/getCities.json/get.jsmodule.exports = function(client, callback) { dbAlias.query( 'select * from City', function(err, rows, fields) { client.context.data = { rows:rows, fields:fields }; callback(); } );}

Page 12: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

9. Async parallel resource access example

/examples/complex/getFsMongoRequest.json/get.jsmodule.exports = function(client, callback) { impress.async.parallel({ file: function(callback) { var filePath = client.hostDir+client.path+'/test.txt'; fs.readFile(filePath, 'utf8', function(error, data) { callback(null, data); }); }, request: function(callback) { var req = impress.http.request({ hostname: 'google.com', port: 80, path: '/', method: 'get' }, function(response) { var data = ''; response.on('data', function(chunk) { data = data+chunk; }); response.on('end', function() { callback(null, data); }); } ); req.on('error', function(e) { callback(null, "Can't get page"); }); req.end(); },...

Page 13: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

...previous example end

/examples/complex/getFsMongoRequest.json/get.js... mongo: function(callback) { dbAlias.testCollection.find({}).toArray(function(err, nodes) { callback(null, nodes); }); } }, function(err, results) { client.context.data = results; callback(); });}---------------------------------------------------------------------------------{ "mongo": [ { "_id": "53547375894c3d3022000001" } ], "file": "?Example text file", "request": "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n<TITLE>302 Moved</TITLE></HEAD><BODY>\n <H1>302 Moved</H1>\nThe document has moved\n <A HREF=\"http://www.google.com.ua/?gws_rd=cr&amp; ei=OWVWU5nHOqOc4wTbjYDgBw\">here</A>.\r\n</BODY></HTML>\r\n"}

Page 14: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

10. Stateful API handler example

/examples/memory/stateful.json/get.jsmodule.exports = function(client, callback) { application.stateTest = application.stateTest || { counter: 0, addresses: [] };

application.stateTest.counter++; application.stateTest.addresses.push( client.req.connection.remoteAddress );

client.context.data = application.stateTest; callback();}

Page 15: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

11. SSE handle example

/examples/events/connect.sse/get.jsmodule.exports = function(client, callback) { client.sse.channel = 'TestEventStream'; callback();}

---------------------------------------------------------------/js/init.jsvar sse = new EventSource("/examples/events/connect.sse");

sse.addEventListener("TestEventStream", function(e) { console.dir({ event: e.event, data: e.data });});

Page 16: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

12. WebSocket handler example

/examples/events/connect.ws/get.jsmodule.exports = function(client, callback) { var connection = client.res.websocket.accept(); connection.send('Hello world'); connection.on('message', function(message) { connection.send('I am here'); }); connection.on('close', function(reasonCode, description) { console.log('disconnected'); }); callback();}---------------------------------------------------------------/js/init.jsws = new WebSocket("ws://127.0.0.1:80/examples/events/connect.ws");ws.onopen = function() {};ws.onclose = function() {};ws.onmessage = function(evt) { console.log("Message from server: "+evt.data);}

Page 17: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

API and FS introspection screens

Page 18: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Deployment patterns

• Installation script with deployment recomendations• Applications Server Configuration /config/*.js

• Start strategies (single, multiple, specialization, sticky)• Multithreading parameters: cluster.js• Network interfaces and port configuration: servers.js• Sandboxes configuration, plugins and access• Impress Applied Controller configuration: cloud.js• Logging configuration: log.js

• Application configuration /applications/name/config/*.js• Database access parameters: databases.js• Virtualhosts: hosts.js• URL-rewriting and reverse proxy configuration: routes.js• Session parameters: sessions.js• Static files and caching parameters: files.js• Application specific configuration files

Page 19: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Server installation (node.js + Impress)

CentOS 6.5 (64bit) minimalcurl http://.../impress/install.sh | sh---------------------------------------------------------------#!/bin/bashyum -y updateyum -y install wgetyum -y groupinstall "Development Tools"cd /usr/srcwget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gztar zxf node-v0.10.26.tar.gzcd node-v0.10.26./configuremakemake installln -s /usr/local/bin/node /binln -s /usr/local/bin/npm /binmkdir /impresscd /impressnpm install impress

Page 20: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Application Server as Linux Daemon

If installing Impress into absolute path /impress

Run /impress/bin/install.sh for:• Setup and configure as Linux daemon• Run at system startup• Auto-restart daemon workers on fails

Run /impress/bin/uninstall.sh for:• Stop Application Server• Remove from system startup• Remove Daemon from system

After install as a service (daemon) you can use:service impress startservice impress stopservice impress restartservice impress updateservice impress status

Page 21: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Application Server Configuration

/config/cloud.jsmodule.exports = { name: "PrivateCloud", type: "standalone", controller: "127.0.0.1", pubSubPort: "3000", reqResPort: "3001", health: "2s"}---------------------------------------------------------------/config/cluster.jsmodule.exports = { check: "http://127.0.0.2/", name: "C1", cookie: "node", strategy: "multiple", // single, specialization, sticky workers: os.cpus().length, gcInterval: 0}

Page 22: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Network interfaces & ports config

/config/servers.jsmodule.exports = { www: { protocol: "http", address: "127.0.0.1", port: 80, applications: ["example", "host2"], nagle: true, slowTime: "1s" }, ssl: { protocol: "https", address: "127.0.0.1", port: 443, key: "example.key", cert: "example.cer" }}

Page 23: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Plugins configuration

/config/plugins.jsmodule.exports = [ "db", "db.schema", "db.mongodb", "db.memcached", "db.mysql", "db.mysql.schema", "impress.log", "impress.security", "impress.security.mongodb", "impress.mail", "impress.uglify", "impress.health", "impress.cloud", "impress.geoip", "impress.websocket", "impress.sse"]

Page 24: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Logging and sandbox configuration

/config/log.jsmodule.exports = { keepDays: 10, writeInterval: "3s", writeBuffer: 64*1024, fileTypes: [ "access", "error", "debug", "slow" ]}---------------------------------------------------------------/config/sandbox.js module.exports = { modules: [ 'global', 'console', 'process', 'impress', 'db', 'domain', 'crypto', 'geoip', 'os', 'Buffer', 'stream', 'nodemailer', 'net', 'http', 'https', 'dgram', 'dns', 'url', 'path', 'fs', 'util', 'events', 'iconv', 'querystring', 'zlib', 'async']}

Page 25: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Virtualhosts and URL-rewriting config

/applications/applicationName/config/hosts.jsmodule.exports = [ "127.0.0.1", "mydomain.com", "*.domainname.com",]---------------------------------------------------------------/applications/applicationName/config/routes.jsmodule.exports = [ { url: "/api/(one|two)/(.*)", rewrite: "/example/[1].json?par1=[2]" }, { url: "/api/(name1|name2|name3)/(.*)", rewrite: "/api/[1]/[2]", host: "example.com", port: 80, slowTime: "1s" }]

Page 26: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Database access configuration

/applications/applicationName/config/databases.jsmodule.exports = { mongoTest: { url: "mongodb://hostName:27017/databaseName", slowTime: "2s", collections: ["collection1", "collection2"], security: true, alias: "alias1" }, system: { url: "mysql://user:password@localhost/dbName", slowTime: 1000, alias: "aliasName" }}

Page 27: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Session and static files serving config

/applications/applicationName/config/sessions.jsmodule.exports = { anonymous: true, cookie: "SID", characters: "ABCDEFGH...fghijkl...456789", length: 64, persist: true, database: "impress"}---------------------------------------------------------------/applications/applicationName/config/files.jsmodule.exports = { minify: false, static: [ "*/css/*", "*/images/*", "*/js/*", "*/favicon.ico", "*/favicon.png" ]}

Page 28: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Примеры и демо-приложение

Page 29: Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)

Thanks for attention!Questions please

Timur ShemsedinovResearch Institute of System Technologies (UA, Kiev), MetaSystems Inc.

mailto:[email protected]://habrahabr.ru/users/marcusaurelius/https://www.npmjs.org/package/impresshttps://github.com/tshemsedinov/impress