簡體   English   中英

在模塊化Sinatra應用程序中標准化API響應

[英]Standardizing api responses in a modular Sinatra application

我正在將api開發為模塊化Sinatra Web應用程序,並希望標准化返回的響應,而不必明確地這樣做。 我認為可以通過使用中間件來實現,但是在大多數情況下都失敗了。 到目前為止,以下示例應用程序是我所擁有的。

config.ru

require 'sinatra/base'
require 'active_support'
require 'rack'

class Person
  attr_reader :name, :surname
  def initialize(name, surname)
    @name, @surname = name, surname
  end
end

class MyApp < Sinatra::Base

  enable :dump_errors, :raise_errors
  disable :show_exceptions

  get('/string') do
    "Hello World"
  end

  get('/hash') do
    {"person" => { "name" => "john", "surname" => "smith" }}
  end

  get('/array') do
    [1,2,3,4,5,6,7, "232323", '3245235']
  end

  get('/object') do
    Person.new('simon', 'hernandez')
  end

  get('/error') do
    raise 'Failure of some sort'
  end
end

class ResponseMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    begin
      status, headers, body = @app.call(env)
      response = {'status' => 'success', 'data' => body}
      format(status, headers, response)
    rescue ::Exception => e
      response = {'status' => 'error', 'message' => e.message}
      format(500, {'Content-Type' => 'application/json'}, response)
    end
  end

  def format(status, headers, response)
    result = ActiveSupport::JSON.encode(response)
    headers["Content-Length"] = result.length.to_s
    [status, headers, result]
  end
end

use ResponseMiddleware
run MyApp

示例(在JSON中):

/string
  Expected: {"status":"success","data":"Hello World"}
  Actual:   {"status":"success","data":["Hello World"]}

/hash (works)
  Expected: {"status":"success","data":{"person":{"name":"john","surname":"smith"}}}
  Actual:   {"status":"success","data":{"person":{"name":"john","surname":"smith"}}}

/array
  Expected: {"status":"success","data": [1,2,3,4,5,6,7,"232323","3245235"]}
  Actual:   {"status":"error","message":"wrong number of arguments (7 for 1)"}

/object
  Expected: {"status":"success","data":{"name":"simon","surname":"hernandez"}}
  Actual:   {"status":"success","data":[]}

/error (works)
  Expected: {"status":"error","message":"Failure of some sort"}
  Actual:   {"status":"error","message":"Failure of some sort"}

如果執行代碼,您將看到/ hash和/ error會返回所需的響應,而其余的則不會。 理想情況下,我不想更改MyApp類中的任何內容。 它目前在Sinatra 1.3.3,ActiveSupport 3.2.9和Rack 1.4.1之上構建。

在irc.freenode.org上#sinatra的幫助下,我設法將其降至所需的水平。 我在MyApp中添加了以下內容:

def route_eval
  result = catch(:halt) { super }
  throw :halt, {"result" => result}
end

然后,我在ResponseMiddleware中更改了以下行:

response = {'status' => 'success', 'data' => body}

response = {'status' => 'success', 'data' => body["result"]}

我所有的測試用例都通過了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM