• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014)
 

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

on

  • 194 views

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

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.

Statistics

Views

Total Views
194
Views on SlideShare
194
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014) Rapid API development examples for Impress Application Server / Node.js (jsfwdays 2014) Presentation Transcript

    • Rapid API development examples for Impress Application Server (Node.js) Timur Shemsedinov Research Institute of System Technologies (UA, Kiev), MetaSystems Inc. mailto:timur.shemsedinov@gmail.com https://github.com/tshemsedinov/impress http://habrahabr.ru/users/marcusaurelius/ https://www.npmjs.org/package/impress
    • 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.
    • 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
    • 1. Simple JSON handler /example/app/examples/simple/jsonPost.json/post.js module.exports = function(client, callback) { client.context.data = { a: 1 }; callback(); } --------------------------------------------------------------- HTTP POST /example/app/examples/simple/jsonPost.json { "a": 1 }
    • 2. Simple AJAX handler with template /examples/simple/ajaxTest.ajax/get.js module.exports = function(client, callback) { client.context.data = { parameterName: client.query.parameterName, }; callback(); } --------------------------------------------------------------- /examples/simple/ajaxTest.ajax/html.template AJAX Request with parameter returning back in template<br> parameterName: @parameterName@ --------------------------------------------------------------- HTTP GET /examples/simple/ajaxTest.ajax?parameterName=parameterValue AJAX Request with parameter returning back in template<br> parameterName: parameterValue
    • 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
    • 4. File system access example /examples/simple/fsAccess.json/get.js module.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 }
    • 5. HTTP-request from API handle example /examples/simple/httpRequest.json/get.js module.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(); }
    • 6. MongoDB (read) access example /examples/mongodb/getData.json/get.js module.exports = function(client, callback) { dbAlias.testCollection.find({}).toArray( function(err, nodes) { client.context.data = nodes; callback(); } ); } --------------------------------------------------------------- HTTP GET mongodb/getData.json [ { "_id": "53547375894c3d3022000001" } ]
    • 7. MongoDB write and metadata examples /examples/mongodb/insertData.json/get.js module.exports = function(client, callback) { dbAlias.testCollection.insert(client.query, function(err) { client.context.data = !err; callback(); }); } --------------------------------------------------------------- /examples/mongodb/getCollections.json/get.js module.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(); }); }
    • 8. SQL-query (MySql) access example /examples/mysql/getCities.json/get.js module.exports = function(client, callback) { dbAlias.query( 'select * from City', function(err, rows, fields) { client.context.data = { rows:rows, fields:fields }; callback(); } ); }
    • 9. Async parallel resource access example /examples/complex/getFsMongoRequest.json/get.js module.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(); }, ...
    • ...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 movedn <A HREF="http://www.google.com.ua/?gws_rd=cr&amp; ei=OWVWU5nHOqOc4wTbjYDgBw">here</A>.rn</BODY></HTML>rn" }
    • 10. Stateful API handler example /examples/memory/stateful.json/get.js module.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(); }
    • 11. SSE handle example /examples/events/connect.sse/get.js module.exports = function(client, callback) { client.sse.channel = 'TestEventStream'; callback(); } --------------------------------------------------------------- /js/init.js var sse = new EventSource("/examples/events/connect.sse"); sse.addEventListener("TestEventStream", function(e) { console.dir({ event: e.event, data: e.data }); });
    • 12. WebSocket handler example /examples/events/connect.ws/get.js module.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.js ws = 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); }
    • API and FS introspection screens
    • 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
    • Server installation (node.js + Impress) CentOS 6.5 (64bit) minimal curl http://.../impress/install.sh | sh --------------------------------------------------------------- #!/bin/bash yum -y update yum -y install wget yum -y groupinstall "Development Tools" cd /usr/src wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz tar zxf node-v0.10.26.tar.gz cd node-v0.10.26 ./configure make make install ln -s /usr/local/bin/node /bin ln -s /usr/local/bin/npm /bin mkdir /impress cd /impress npm install impress
    • 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 start service impress stop service impress restart service impress update service impress status
    • Application Server Configuration /config/cloud.js module.exports = { name: "PrivateCloud", type: "standalone", controller: "127.0.0.1", pubSubPort: "3000", reqResPort: "3001", health: "2s" } --------------------------------------------------------------- /config/cluster.js module.exports = { check: "http://127.0.0.2/", name: "C1", cookie: "node", strategy: "multiple", // single, specialization, sticky workers: os.cpus().length, gcInterval: 0 }
    • Network interfaces & ports config /config/servers.js module.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" } }
    • Plugins configuration /config/plugins.js module.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" ]
    • Logging and sandbox configuration /config/log.js module.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' ]}
    • Virtualhosts and URL-rewriting config /applications/applicationName/config/hosts.js module.exports = [ "127.0.0.1", "mydomain.com", "*.domainname.com", ] --------------------------------------------------------------- /applications/applicationName/config/routes.js module.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" } ]
    • Database access configuration /applications/applicationName/config/databases.js module.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" } }
    • Session and static files serving config /applications/applicationName/config/sessions.js module.exports = { anonymous: true, cookie: "SID", characters: "ABCDEFGH...fghijkl...456789", length: 64, persist: true, database: "impress" } --------------------------------------------------------------- /applications/applicationName/config/files.js module.exports = { minify: false, static: [ "*/css/*", "*/images/*", "*/js/*", "*/favicon.ico", "*/favicon.png" ] }
    • Examples: Demo Applications
    • Thanks for attention! Questions please Timur Shemsedinov Research Institute of System Technologies (UA, Kiev), MetaSystems Inc. mailto:timur.shemsedinov@gmail.com http://habrahabr.ru/users/marcusaurelius/ https://www.npmjs.org/package/impress https://github.com/tshemsedinov/impress