nestia-web

2.1.23 • Public • Published

nestia-web

Nestia Web Component

init options


{
    common: {
        expressApp: null,
        listenHostname: '',
        listenPort: 3000,
    },
    cache: {
        impl: 'memory',
    },
    log: {
        path: '',
        level: '',
        extraZipStreams: [],
        takeOverConsole: false,
        extraOutputStreams: {
            info: process.stdout,
            error: process.stderr,
        },
    },
    ajax: {
        timeout: 10000,
        slowThreshold: 3000,
        defaultHeaders: {
            "X-Requested-With": "Nestia Web component V2.0"
        },
        agentOptions:{}
    },
    manifest: {
        path: '',
        name: '',
    },
    config: {
        server: '',
    },
    monitor: {
        prefix: '',
        suffix: '',
        mem: true,
        cpu: true,
        req404: true,
        req5xx: true,
    },
    isPrimaryProcess: cluster.isPrimary || cluster.isMaster
}

  • common.expressApp (object) optional,Express.app object.
  • common.listenHostname (string) optional, hostname or ip http server listens on, used for config server callback.
  • common.listenPort (number) optional,port number http server listens on, used for config server callback.
  • cache.impl (string) optional, cache implementation, default is memory.
  • log.path (string) optional, directory to save log files.
  • log.level (string) optional, minimal level written to log file,default is info.
  • log.extraZipStreams (array) optional, streams for access log.
  • log.takeOverConsole (bool) optional, default false, indicate log module take over system console, thus all console message will be pipe to log file.
  • log.extraOutputStreams (Object) optional, default null, extra log output stream, should be {info:[...Writable],error:[...Writable]}.
  • ajax.timeout (number) optional, default timeout in millisecond, default is 10000.
  • ajax.slowThreshold (number) optional, default slow log time limit in millisecond, all backend response time greater than limit will be logged to slow log file, default value is 50.
  • ajax.defaultHeaders (object) optional, default headers send to backend, default value is {'x-requested-with':'Nestia Web Server 1.0'}.
  • ajax.agentOptions (object) optional, extra agent options will pass to http/https agent, also will applied to globalAgent.
  • manifest.path (string) optional, directory contain manifest file.
  • manifest.name (string) optional, manifest name to load.
  • config.server (string) optional, configuration server .
  • config.hostPath (string) optional, configuration server .
  • monitor.prefix (string) optional, prefix of all monitor keys.
  • monitor.suffix (string) optional, suffix of all monitor keys.
  • monitor.mem (bool) optional, auto monitor memory usage, default is false.
  • monitor.cpu (bool) optional, auto monitor cpu usage, default is false.
  • monitor.req404 (bool) optional, monitor 404 requests, default is false.
  • monitor.req5xx (bool) optional, monitor 5xx requests, default is false.
  • isPrimaryProcess (bool) optional, indicate current process is primary in cluster mode, monitor module will act differently when run as a worker process.

Monitor

Usage:

Init:

@deprecated

var NestiaWeb = require('nestia-web'); //this line must @ top ,before any routes or app filters. app.use(NestiaWeb.requestFilter());

.....

var Monitor = NestiaWeb.monitor; Monitor.init(configObj);

Monitor Config:

{ app: Express.app object (obj,required) prefix: monitor default prefix (string,optional) suffix: monitor default suffix (string,optional) mem: monitor memory usage (boolean,optional) cpu: monitor cpu usage (boolean,optional) mon404: monitor 404 response (boolean,optional) mon5xx: monitor 5xx response (boolean,optional) monitorPath: the path for express which remove graph drawer used to get monitor indicators and values }

Request filter

  1. Used to adept nestia ip rule,when using request.ip property.
  2. add req.realUrl property presents the url send to nginx.

Request Utils

Provides function to resolve request headers,such as accept-language or user-agent.

getUAInfo

param:

  • req: express request object

return:

 {
     isBot: false,
     isNestiaServer: false,
     isNestiaClient: true,
     isNestiaBusClient: false,
     isNestiaAppClient: false,
     isNestiaLotteryClient: false,
     isNestiaMalaysiaLotteryClient: false,
     isNestiaAgentClient: true,
     nestiaClientId: "b23b2e8cc2bb3e38" / "60D42196-426C-4717-91B1-A7A72FE48AF9", #exists only when isNestiaClient === true or isNestiaAgentClient === true
     isWinPhone: false,
     isIPhone: false,
     isIPad: false,
     isAndroid: false,
     isOtherMobile: false,
     isMobile: false,
     isWechatMiniProg: false,
     platform: "windows" | "ios" | "android" | "linux" | "macos" | "whatsapp" | "compatible" | "unknown",
     platformVersion: "10.3.1",
     browser: "msie" | "opera" | "firefox" | "chrome" | "facebook" | "weixin" | "safari" | "unknown",
     browserVersion: "10.3.1"
 }
getLangInfo

param:

  • req: express request object
  • is4PC: true means client is requesting a web page for PC not mobile device.

return:

 {
     languages: {
         "zh-CN": "0,8",
         "en": "0,6"
     },
     primaryLanguage: ["zh-CN"],
     isEnglish: false,
     lang: "zh-cn" | "en"
 }

Log

  1. provide an logger by using getLogger
  2. automatically zip logs
  3. automatically removes oldlogs
  4. Requires init
  5. NestiaWeb.logger's method can be called at any time, but it won't output any data until init finished.

init options:

{
       dir:path.join(__dirname,'/../logs'),
       streams:FileStreamRotator.getStream({...}) | [FileStreamRotator.getStream({...})]
}

Usage Example:

NestiaWeb.logger.info('some text',someObject);

Manifest

let NestiaWeb=require('nestia-web');
let manifest=NestiaWeb.manifest;

let value=manifest.get('prop1.prop2.prop3');
......

Ajax

Ajax API

Request Options

demo:


{
    server:'lottery',
    version:'v5.0'
    path:'/toto/broadcast'
    data:{
        key1:1234,
        key2:5678
    },
    method:'POST',
    timeout:800,
    reqContentType:'form',
    resContentType:'json',
    headers:{
        SomeUserDefinedHeader:'this will pass to server'
    },
    isWeb:true,
    anonymous:true,
    cname:'toto_broadcast',
    passClientIP:false,
    req:req,
    res:res
}

  • server: (string) (required) Server code defined in manifest.
  • version: (string) (optional) Version to replace '${version}' part in url.
  • path: (string) (required) Api path apart from url defined in manifest.
  • data: (object) (optional) Data will send to server.It should be a simple object.
  • method: (string) (optional) Http method,default is 'GET'.
  • timeout: (number) (optional) Timeout (microseconds) before server complete response,default is defined in config or init option DEFAULT_TIMEOUT.
  • reqContentType (deprecated alias dataType): (string) (optional) request data format,only support 'json' and 'form'(default).
  • resContentType (deprecated alias contentType): (string) (optional) Content format.If contentType set 'json' or server response with header 'content-type:application/json', response body will be decode automatically.
  • headers: (object) (optional) Headers passed to server.Note:if req object is set,most of req.headers' property will passed to backend,no need to redefine headers in this option.
  • isWeb: (bool) (optional) If true, and exists cookie named 'N1',then cookie N1's value will replace default Accept-Language value.Default is false.
  • anonymous: (bool) (optional) If false, and exists cookie named 'token',then a header named 'Authorization' will be set with value of cookie 'token'.
  • noCache: (bool) (optional) If true, headers named 'If-Modified-Since','If-None-Match' will be removed from header ,and 'Cache-Control' will be set 'no-cache'. Default is true.
  • passClientIP: (bool) (optional) If true, headers ('X-Forwarded-For','X-Real-IP') will be passed to server. Default is true.
  • req: (obj) (optional) (*required by proxy) By default,most of headers in req will pass to backend request.In proxy method,request's body stream will piped to backend request.
  • res: (obj) (unnecessary)(*required by proxy) Proxy will handle response,when reject happened.Only if ret.status === 0 ,proxy don't handle response,you should end response, such as res.status(500).end() .
Response Data (also as reject error)

{
    ok: false,
    status: 0,
    message: '',
    error: null,
    data: {},
    raw: null,
    headers: null,
    totalCount: null,
    duration: [0, 123000]
}

  • ok: (bool) indicates request is successful.
  • status: (number) http response code from backend server.
  • message: (string) error message when exception or error happened.
  • error: (Error) Error object,if exists.
  • data: (*) parsed server response content.Object if content-type option set "json",string if content-type set something else.
  • raw: (string) original server response text,null when calling proxy method.
  • headers: (object) response headers.
  • duration (array) [seconds,nanoseconds], time used from request start to finish.
  • totalCount: (number) same value of response's headers["X-Total-Count"],null if header not exists.
Ajax.request
NestiaWeb.ajax.request({
        server: 'property',
        version: 'v4.6',
        timeout: 3000,
        path: path,
        method: 'POST',
        isWeb:true,
        req: req, 
        performance: false,
        proxy: 'http://someuser:password@127.0.0.1:7666',
        headers: {
            'origin': 'https://property-staging.nestia.com'
        }
    }).then((data) => {
        res.render('somepage',data.data);
    }, (err) => {
        req.app.locals.logger.error('error request backend API:' + err.message, err);
        if (err.status) {
            res.status(err.status).end();
        }else{
            res.status(500).end();
        }
    });
Ajax.proxy
NestiaWeb.ajax.proxy({
        server: 'property',
        path: path,
        method: 'POST',
        isWeb:true,
        req: req,
        res: res,
        headers: {
            'origin': 'https://property-staging.nestia.com'
        }
    }).then((data) => {
    }, (err) => {
        NestiaWeb.logger.error('error upload property image:' + err.message, err);
        if (!err.status) {
            res.status(500).end();
        }
    });
Ajax.requestAll
  • This method is a little like Promise.all
  • When one of requests fails,you will always get a resolve callback, which is different from Promise.all.
  • You can use data[n].ok to check whether request fails, and also you can get status, and raw data if exists.
NestiaWeb.ajax.request([
    {
        server: 'property',
        version: 'v4.6',
        timeout: 3000,
        path: '/nearby'
    },
    {
        server: 'news',
        version: 'v4.8',
        path: '/news'
    }
]).then((datas) => {
        let propertyData=datas[0];
        let newsData=datas[1];
        
        //assume property backend never fails.
        if(!newsData.ok){
            //news api fails
            res.render('onlyProperty',propertyData.data);        
        }else{        
            res.render('fullContent',{property:propertyData.data,news:newsData.data});
        }
    });

Cache


let NestiaWeb=require('nestia-web');
let cache=NestiaWeb.cache;
//set a cache
//timeout is numeric presents seconds,default value is 300 seconds.
//when timeout is negitave number, the cache record will never expire.
cache.set('propName','propValue',30);
//get value
cache.get('propName').then(function(val){
    //val should equal 'propValue'
});

//memory cache cleanup has 60 seconds deviation
setTimeout(function(){
    cache.get('propName').then(function(val){
        //val should be null 
    });
},30+60000);



cache.set('anotherPropName','anotherPropValue',30).then(()=>{
  cache.set('anotherPropName',null,30);
});

//current memory cache implements synchronously.
cache.get('anotherPropName').then(function(val){
    //val should be null
});

Config

An easy way to access nestia config api.

Config.getConfig

parameters:

  1. configName: (required) Config file's name.
  2. contentType: (optional) See AJAX.requestOptions.contentType.
  3. useCache: (optional) Use local memory cache, default is true.

demo:


nestiaWeb.config.getConfig(
    'app_config_' + ('' + req.params['version']).replace('.', '_') + '.json',
    'json',
    false
).then(function (result) {
    try {
        var result = JSON.parse(result.content);
        // var lang = (/zh-cn|zh-han[st]-/.test((req.headers['accept-language'] || '').toLowerCase())) ? 'cn' : 'en';
        var platform = /(IOS|iPhone)/.test(req.headers['user-agent']) ? 'ios' : 'adr';
        res.setHeader('Content-Type', 'application/json;charset=UTF-8');
        res.send(JSON.stringify(result[platform]));
    } catch (e) {
        res.setHeader('Content-Type', 'text/plain');
        res.set('X-Error', 500);
        res.status(500);
        res.send(e.message + "<br/>\r\nOriginal content:" + result.data.content);
    }

}, function (err) {
    "use strict";
    res.setHeader('Content-Type', 'text/plain');
    res.set('X-Error', err.status);
    res.status(500);
    res.send('Error:' + err.status)
});

Config.setConfig

parameters:

  1. configName: (required) Config file's name.
  2. content: (required) Config value content. If content is plain object, it will be stringified to json string.If not, it will be converted to string.

demo:


nestiaWeb.config.setConfig(
    'wechat_config',
    {content:'this is a way to access wechat api'}
).then(function (result) {
    try {
        var result = JSON.parse(result.content);
        //result is object {content:'this is a way to access wechat api'}
    } catch (e) {
        res.setHeader('Content-Type', 'text/plain');
        res.set('X-Error', 500);
        res.status(500);
        res.send(e.message + "<br/>\r\nOriginal content:" + result.data.content);
    }

}, function (err) {
    "use strict";
    res.setHeader('Content-Type', 'text/plain');
    res.set('X-Error', err.status);
    res.status(500);
    res.send('Error:' + err.status)
});

Readme

Keywords

none

Package Sidebar

Install

npm i nestia-web

Weekly Downloads

5

Version

2.1.23

License

ISC

Unpacked Size

380 kB

Total Files

109

Last publish

Collaborators

  • ds3783_npm