Javascript对象路线图

时间:2018-03-09 04:06:00

标签: javascript node.js object

所以我需要构建一个可以将URL路径映射到目标服务器的对象,如下所示:

/api         :   http://apiserver:8000
/api/v1      :   http://apiv1server:8888
/api/v1/foo  :   http://foo:8080
/foo         :   http://foo:8080

function addRoute(path, server) {
  setRoute(path, server)
}
addRoute('/api', 'http://apiserver:8000')
addRoute('/api/v1', 'http://apiv1server:8888')

每个查找应该与最具体的路由匹配,所以我最初的想法是这样的对象:

 let map = {
   api: {
     v1: {
       default: 'http://apiv1server:8000',
       foo: 'http://foo:8080'
     },
     default: 'http://apiserver:8000'
   },
   foo: 'http://foo:8080'
 }

这样你就可以使用这样的简单查找函数:

function lookup(path) {
  let result = null
  path.split('/').forEach(key => {
    result = map[key] || map[key].default
  })
  return result
}

但是尝试通过点(斜线)符号设置对象已经证明非常困难,任何想法?

或者还有另一种更简单的方法吗?

2 个答案:

答案 0 :(得分:1)

[top_bg addSubview:logoView];

你可以尝试一下。

答案 1 :(得分:0)

谢谢,因为我找不到设置路线的好方法,所以我采用下面的递归方法:

let RouteMap = function (def) {
  this.defaultRoute = def
  this.map = {}
}

RouteMap.prototype = {
  lookup: function (path) {
    console.log('ROUTE MAP LOOKUP: ', path)
    if (path) {
      let parts = path.split('/')
      let p = parts.shift()
      if (this.map[p] instanceof RouteMap) {
        return this.map[p].lookup(parts.join('/')) || this.defaultRoute
      } else {
        return this.map[p]
      }
    } else {
      return this.defaultRoute
    }
  },
  set: function (path, val) {
    console.log('ROUTE SET: ', path, val)
    if (path) {
      let parts = path.split('/')
      let p = parts.shift()
      if (parts.length > 0) {
        this.map[p] = this.map[p] || new RouteMap()
        this.map[p].set(parts.join('/'), val)
      } else {
        this.map[p] = val
      }
    } else {
      throw new Error('Path is', path)
    }
  },
  addRoutesFromEnv: function (env) {
    for (let key in process.env) {
      if (key.startsWith('SERVICE_')) {
        let val = process.env[key]
        let parts = val.split('::')
        if (parts.length === 2) {
          this.set(parts[0], parts[1])
          // this.add(parts[0], parts[1]) // /api/v1::http://v1host:8000
        } else {
          console.warn('Invalid SERVICE_NAME environment variable: should be SERVICE_NAME=/path/to/proxy::http://host:port, ', key)
        }
      }
    }

    console.log('ROUTE MAP: ', JSON.stringify(this.map, null, 2))
  }
}

module.exports = RouteMap