2014-01-22 93 views
1

我正在爲外部API構建節點包裝器,並且解析JSON響應時出現問題。下面的代碼發出請求:解析節點中的JSON API

https = require "https" 
querystring = require "querystring" 

API_HOST = "api.lob.com" 
API_PATH = "/v1" 

startResponseHandler = (req, cb) -> 
    if typeof cb isnt "function" then console.log "Error: callback needs to be a function!" 
    req.on 'response', (res) -> 
    response = '' 
    res.setEncoding 'utf8' 
    res.on 'data', (stream) -> 
     response += stream 
    res.on 'end',() -> 
     error = null 
     try 
     response = JSON.parse response 
     if res.statusCode != 200 or 201 
      response = null 
      error = new Error response.error.message 
      error.name = response.error.type 
      error.code = response.error.code 
      error.param = response.error.param 
     catch e 
     error = new Error "Invalid JSON" 
     response = null 
     cb error, response 
    req.on 'error', (error) -> 
    cb error 

module.exports = lob = (api_key) -> 

    # This function makes the request 
    makeRequest = (method, path, data, cb) -> 
    data = querystring.stringify data 
    options = 
     hostname: API_HOST 
     path: "#{API_PATH}/#{path}" 
     method: method 
     auth: "#{api_key}:" 
     headers: 
     'Content-Type' : 'application/x-www-form-urlencoded' 
     'Content-Length' : data.length 
    req = https.request options 
    startResponseHandler req, cb 
    req.write data if method is "POST" or "PUT" 
    req.end() 

    # GET, POST, DELETE, PUT functions 
    _get = (path, cb) -> 
    makeRequest "GET", path, {}, cb 

    _post = (path, data, cb) -> 
    makeRequest "POST", path, data, cb 

    _del = (path, cb) -> 
    makeRequest "DELETE", path, {}, cb 

    _put = (path, data, cb) -> 
    makeRequest "PUT", path, data, cb 

    # Jobs 
    jobs: 

    createJob: (data, cb) -> 
     _post "/jobs/", data, cb 

而下面的代碼被寫入測試包裝器:

api_key = "test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc" 

lob  = require('../src/lob')(api_key) 
should = require("should") 
chai = require("chai") 

data = 
    name: "Michigan fan letter" 
    to: "adr_43769b47aed248c2" 
    from: "adr_7f9ece71fbca3796" 
    object1: "obj_7ca5f80b42b6dfca" 
    object2: "obj_12128d3aad2aa98f" 

describe "Job", -> 
    @timeout(10000) 
    describe "create", -> 
    it "should create a job with address_id", (done) -> 
     lob.jobs.createJob data , (new_job) -> 
     new_job['name'].should.equal(data['name']) 
     done() 

然而,當我運行摩卡試驗($ mocha --compilers coffee:coffee-script)我收到以下錯誤:

1) Job create should create a job with address_id: 

     + expected - actual 

     +"Michigan fan letter" 
     -"Error" 

編輯

下面是從streamres.on 'data'響應:

{ 
    "id": "job_7ecc50bea15178b8e07a", 
    "name": "Michigan fan letter", 
    "price": "1.26", 
    "to": { 
     "id": "adr_43769b47aed248c2", 
     "name": "Harry Zhang", 
     "email": "[email protected]", 
     "phone": "5555555555", 
     "address_line1": "123 Test Street", 
     "address_line2": "Unit 199", 
     "address_city": "Mountain View", 
     "address_state": "CA", 
     "address_zip": "94085", 
     "address_country": "UNITED STATES", 
     "date_created": "2013-07-20T05:53:25+00:00", 
     "date_modified": "2013-07-20T05:53:25+00:00", 
     "object": "address" 
    }, 
    "from": { 
     "id": "adr_7f9ece71fbca3796", 
     "name": "Harry Zhang", 
     "email": "[email protected]", 
     "phone": "5555555555", 
     "address_line1": "123 Test Avenue", 
     "address_line2": "Unit 401", 
     "address_city": "Seattle", 
     "address_state": "WA", 
     "address_zip": "98122", 
     "address_country": "UNITED STATES", 
     "date_created": "2013-07-20T05:55:19+00:00", 
     "date_modified": "2013-07-20T05:55:19+00:00", 
     "object": "address" 
    }, 
    "status": "processed", 
    "tracking": null, 
    "packaging": { 
     "id": "1", 
     "name": "Smart Packaging", 
     "description": "Automatically determined optimal packaging for safe and secure delivery", 
     "object": "packaging" 
    }, 
    "service": null, 
    "objects": [ 
     { 
      "id": "obj_7ca5f80b42b6dfca", 
      "name": "Michigan is great", 
      "quantity": "1", 
      "full_bleed": "0", 
      "double_sided": "0", 
      "date_created": "2013-07-20T05:57:32+00:00", 
      "date_modified": "2013-07-20T05:57:32+00:00", 
      "setting": { 
       "id": "101", 
       "type": "Documents", 
       "description": "Color Document", 
       "paper": "20lb Paper Standard", 
       "width": "8.500", 
       "length": "11.000", 
       "color": "Color", 
       "notes": "50 cents per extra page", 
       "object": "setting" 
      }, 
      "url": "http://assets.lob.com/obj_7ca5f80b42b6dfca", 
      "object": "object" 
     }, 
     { 
      "id": "obj_12128d3aad2aa98f", 
      "name": "GO BLUE", 
      "quantity": "1", 
      "full_bleed": "0", 
      "double_sided": "0", 
      "date_created": "2013-07-31T00:58:35+00:00", 
      "date_modified": "2013-07-31T00:58:35+00:00", 
      "setting": { 
       "id": "100", 
       "type": "Documents", 
       "description": "Black and White Document", 
       "paper": "20lb Paper Standard", 
       "width": "8.500", 
       "length": "11.000", 
       "color": "Black and White", 
       "notes": "12 cents per extra page", 
       "object": "setting" 
      }, 
      "url": "http://assets.lob.com/obj_12128d3aad2aa98f", 
      "object": "object" 
     } 
    ], 
    "date_created": "2014-01-25T03:10:10+00:00", 
    "date_modified": "2014-01-25T03:10:10+00:00", 
    "object": "job" 
} 

這完全符合了在documentation

{ 
    "id": "job_754d8b14dd31587d6873", 
    "name": "Michigan fan letter", 
    "price": "0.96", 
    "to": { 
     "id": "adr_43769b47aed248c2", 
     "name": "Harry Zhang", 
     "email": "[email protected]", 
     "phone": "5555555555", 
     "address_line1": "123 Test Street", 
     "address_line2": "Unit 199", 
     "address_city": "Mountain View", 
     "address_state": "CA", 
     "address_zip": "94085", 
     "address_country": "UNITED STATES", 
     "date_created": "2013-07-20T05:53:25+00:00", 
     "date_modified": "2013-07-20T05:53:25+00:00", 
     "object": "address" 
    }, 
    "from": { 
     "id": "adr_7f9ece71fbca3796", 
     "name": "Harry Zhang", 
     "email": "[email protected]", 
     "phone": "5555555555", 
     "address_line1": "123 Test Avenue", 
     "address_line2": "Unit 401", 
     "address_city": "Seattle", 
     "address_state": "WA", 
     "address_zip": "98122", 
     "address_country": "UNITED STATES", 
     "date_created": "2013-07-20T05:55:19+00:00", 
     "date_modified": "2013-07-20T05:55:19+00:00", 
     "object": "address" 
    }, 
    "status": "processed", 
    "tracking": null, 
    "packaging": { 
     "id": "1", 
     "name": "Smart Packaging", 
     "description": "Automatically determined optimal packaging for safe and secure delivery", 
     "object": "packaging" 
    }, 
    "service": null, 
    "objects": [ 
     { 
      "id": "obj_7ca5f80b42b6dfca", 
      "name": "Michigan is great", 
      "quantity": "1", 
      "full_bleed": "0", 
      "double_sided": "0", 
      "date_created": "2013-07-20T05:57:32+00:00", 
      "date_modified": "2013-07-20T05:57:32+00:00", 
      "setting": { 
       "id": "101", 
       "type": "Documents", 
       "description": "Color Document", 
       "paper": "20lb Paper Standard", 
       "width": "8.500", 
       "length": "11.000", 
       "color": "Color", 
       "notes": "50 cents per extra page", 
       "object": "setting" 
      }, 
      "object": "object" 
     } 
    ], 
    "date_created": "2014-01-18T19:52:27+00:00", 
    "date_modified": "2014-01-18T19:52:27+00:00", 
    "object": "job" 
} 

這裏的例子響應是JSON.parse response

{ id: 'job_9973e060bd8147f97f5f', 
    name: 'Michigan fan letter', 
    price: '1.26', 
    to: 
    { id: 'adr_43769b47aed248c2', 
    name: 'Harry Zhang', 
    email: '[email protected]', 
    phone: '5555555555', 
    address_line1: '123 Test Street', 
    address_line2: 'Unit 199', 
    address_city: 'Mountain View', 
    address_state: 'CA', 
    address_zip: '94085', 
    address_country: 'UNITED STATES', 
    date_created: '2013-07-20T05:53:25+00:00', 
    date_modified: '2013-07-20T05:53:25+00:00', 
    object: 'address' }, 
    from: 
    { id: 'adr_7f9ece71fbca3796', 
    name: 'Harry Zhang', 
    email: '[email protected]', 
    phone: '5555555555', 
    address_line1: '123 Test Avenue', 
    address_line2: 'Unit 401', 
    address_city: 'Seattle', 
    address_state: 'WA', 
    address_zip: '98122', 
    address_country: 'UNITED STATES', 
    date_created: '2013-07-20T05:55:19+00:00', 
    date_modified: '2013-07-20T05:55:19+00:00', 
    object: 'address' }, 
    status: 'processed', 
    tracking: null, 
    packaging: 
    { id: '1', 
    name: 'Smart Packaging', 
    description: 'Automatically determined optimal packaging for safe and secure delivery', 
    object: 'packaging' }, 
    service: null, 
    objects: 
    [ { id: 'obj_7ca5f80b42b6dfca', 
     name: 'Michigan is great', 
     quantity: '1', 
     full_bleed: '0', 
     double_sided: '0', 
     date_created: '2013-07-20T05:57:32+00:00', 
     date_modified: '2013-07-20T05:57:32+00:00', 
     setting: [Object], 
     url: 'http://assets.lob.com/obj_7ca5f80b42b6dfca', 
     object: 'object' }, 
    { id: 'obj_12128d3aad2aa98f', 
     name: 'GO BLUE', 
     quantity: '1', 
     full_bleed: '0', 
     double_sided: '0', 
     date_created: '2013-07-31T00:58:35+00:00', 
     date_modified: '2013-07-31T00:58:35+00:00', 
     setting: [Object], 
     url: 'http://assets.lob.com/obj_12128d3aad2aa98f', 
     object: 'object' } ], 
    date_created: '2014-01-25T23:12:37+00:00', 
    date_modified: '2014-01-25T23:12:37+00:00', 
    object: 'job' } 
+2

你有沒有在'res.on'data''裏面看過'stream'來看看它是否是你期望的呢? 'res.on'end''中的'response'一樣。 –

+0

我沒有記錄內容,但返回了一個201頭文件,顯示POST請求已成功完成 – Anconia

+0

開始記錄它,如果'JSON.parse'在抱怨,那麼也許你沒有得到你認爲你的數據'重新獲得。 –

回答

2

我看到的數據該代碼中存在三個問題。我通常不使用CoffeeScript。所以,如果我誤讀了請糾正我:

  1. 回調被稱爲像這樣:但是

    cb error, response 
    

    第一個參數是一個錯誤的對象,第二個參數是響應,在測試中回調是這樣的:

    lob.jobs.createJob data , (new_job) -> 
         new_job['name'].should.equal(data['name']) 
    

    所以new_job是錯誤的對象。但這並不能解釋所有情況,因爲你出現錯誤。但即使沒有錯誤,new_job的值也不會作爲迴應。

    測試顯示字符串Error是實際值的原因是Error對象有一個name字段,該字段被設置爲異常類的名稱。 (所以new Error().name評估爲"Error"。)

  2. 這部分代碼也看上去不正確:

    try 
        response = JSON.parse response 
        if res.statusCode != 200 or 201 
        response = null 
        error = new Error response.error.message 
        error.name = response.error.type 
        error.code = response.error.code 
        error.param = response.error.param 
    catch e 
        error = new Error "Invalid JSON" 
        response = null 
    cb error, response 
    

    if分支response設置爲null然後的response某些字段進行訪問。這會導致異常。由於try... catch子句的設置方式,此異常將被解釋爲不良的JSON。該try... catch條款應被縮小到只覆蓋JSON.parse電話:

    try 
        response = JSON.parse response 
    catch e 
        error = new Error "Invalid JSON" 
        response = null 
    
  3. 這個測試是不正確的:

    if res.statusCode != 200 or 201 
    

    它成爲JavaScript的:

    if (res.statusCode !== 200 || 201) 
    

    ||品牌後面的部分它總是如此。像下面的CoffeeScript代碼的東西似乎是何意:

    if res.statusCode not in [200, 201] 
    

所以,如果請求成功與否並不重要。由於第三個問題,if測試將始終爲真,分支始終會被採用,第二個問題將始終發生。所以摩卡測試總是會失敗。

+0

快速提示 - 使用此設置,如果我放入'console.log res.statusCode',它將返回'200' – Anconia

+0

因此,它不能解決您的緊急問題。夠公平的,但它仍然是不好的代碼。 – Louis

+0

同意 - 並感謝您指出:-) – Anconia