Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

使用HTTP状态码处理业务异常

  以前有写过一篇关于提倡使用正确HTTP状态码的文章,最近在设计REST风格的API,正好把这个概念更深入的贯彻。我们不是为了满足某些奇怪的规范或奇怪的范式而把自己的概念局限死,而是为了让设计出来的API更容易使用,逻辑上更正确,维护起来更轻松。
  目前网络上大部分API设计都不是RESTful的,或许有些API正在试图这么做,但也只是形式上的实现。只是硬着头皮让自己去满足一些规范类的东西而已。比如百度网盘的API,现在确实提供了一套REST风格的。但只有请求的方法和URL设计是REST风格,所有相应依然是200,实体数据自带状态码。
  比如有这样的场景。点击某个按钮,按钮变成disabled状态,同时向服务器发起请求,等到请求完成之后再做相应的处理,并恢复按钮状态。也许我们会这么写代码。
$button.click(function(){
  $button.attr("disabled","disabled");
  $.post("/api",function(e){
    if(e.error){
      alert(e.message);
    }else{
      //TODO
    };
    $button.removeAttr("disabled");
  });
});
  乍看之下,这个逻辑确实没问题。但即使在API设计上无论什么状态都返回200也无法保证整个请求永远响应200。可能由于网络问题响应502,可能由于服务器配置问题响应403,诸如此类的各种情况都有可能发生。这个代码只考虑了请求成功的请求,只处理了API中的业务状态。当HTTP错误时请求无法完成时,回调不会被调用,按钮将无法恢复可点击状态。我们可能需要这么写代码
$button.click(function(){
  $button.attr("disabled","disabled");
  $.post("/api",function(e){
    if(e.error){
      alert(e.message);
    }else{
      //TODO
    };
    $button.removeAttr("disabled");
  }).fail(function(e){
    alert("未知错误");
    $button.removeAttr("disabled");
  });
});
  这样的代码中存在两处错误处理,整个程序的逻辑连贯性就丧失了。如果API使用HTTP状态码来处理业务状态的话,我们就可以这么写: $button.click(function(){
  $button.attr("disabled","disabled");
  var api=$.post("/api.PHP").always(function(e){
    $button.removeAttr("disabled");
  });
  //成功
  api.then(function(e){
    //TODO
  });
  //失败
  api.fail(function(e){
    var data;
    try{
      data=$.parseJSON(e.responseText);
    }catch(x){
      data=e.statusText;
    };
    alert(data);
  });
});
  这样的代码逻辑显然更清晰,维护起来也更省力。如果嫌fail方法里面没有自带JSON解析的话可以进一步封装。   
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^