27

REST API を作成していて、問題に遭遇しました。検証エラーを返す最良の方法は何ですか。

これまで、一般的なエラー コードにダンプされたエラー メッセージを返してきました (たとえば、不適切な要求としましょう)。

{
    "status": 400,
    "error": {
        "code": 1, // General bad request code
        "message": [
                "The Key \"a\" is missing",
                "The Key \"b\" is missing",
                "The Key \"c\" is missing",
                "Incorrect Format for field \"y\""
         ]
    }

)

適切な API 応答がどのように見えるべきかについてもう少し調査した結果、次のオプションを考えました。

  1. 最初に発生したエラーで停止し、特定のエラー コードを含む応答を返します

    {
       "status": 400, //Same as the HTTP header returned
       "error" {
            "code": 1, // Specific field validation error code
            "message": "Field \"x\" is missing from the array structure",
            "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
            "more_info" => "www.api.com/help/errors/1"
        }
    )
    
  2. すべてのリクエスト データを解析し、複数のフィールド検証エラーを返します。

    {
      "status": 400,
      "error": {
        "code": 1 //General bad Request code
        "message": "Bad Request",
        "developer_message": "Field validation errors."
        "more_info": "www.api.com/help/errors/1",
        "error_details": {
                0: {
                        "code": 2 // Specific field validation error code
                        "message": "Field \"x\" is missing from the array structure",
                        "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
                        "more_info": "www.api.com/help/errors/2"
                    },
    
                1: {
                        "code": 3 // Specific field validation error code
                        "message": "Incorrect Format for field \"y\"",
                        "developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
                        "more_info": "www.api.com/help/errors/3"
                   }
                       }
          }
      }
    

私の意見では、オプション 2 が正しい方法です (開発者/エンド ユーザーにより有用な情報が提供され、サーバーの負荷が低くなる可能性があります (リクエストが少ない/有効なデータを再検証する必要がない/署名を計算してユーザーを認証する必要がない) ))、しかし、ベストプラクティスとは何か、この種の問題を処理する別の方法があるかどうかをさまよっています。

また、スクリプトのフローで致命的なエラーが 1 つ発生した場合でも、オプション 1 は有効だと思います (検証エラーではありません)。

コードは簡単に理解できるように単純な配列であることに注意してください。応答形式は JSON または XML になります。

4

6 に答える 6

24

Facebook の Graph APIを見てみましょう。これは大きな打撃を受け、非常に多くのエラーが生成される可能性が高くなります。API エラーで Facebook が返す内容は次のとおりです。

 {
   "error": {
     "message": "Message describing the error", 
     "type": "OAuthException", 
     "code": 190,
     "error_subcode": 460,
     "error_user_title": "A title",
     "error_user_msg": "A message"
   }
 }

彼らは Graph API を可能な限り便利なものにしようとしていますが、コードとサブコード ( Ref ) で特定のエラーを返すようです。各エラーには独自のコードがあるという事実は、デバッグの開始点として、そのコードまたはメッセージを簡単に検索できることを意味します。公式のエラー応答にエラー メッセージが蓄積されないのは、おそらくそのためです。それが Facebook にとって十分で便利であれば、おそらく私たちにとっても十分でしょう。

エラー応答の例:

{
  "error": {
    "message": "(#200) Must have a valid access_token to access this endpoint", 
    "type": "OAuthException", 
    "code": 200
  }
}

"error": {
  "message": "(#604) Your statement is not indexable. The WHERE clause must contain 
   an indexable column. Such columns are marked with * in the tables linked from
   http://developers.facebook.com/docs/reference/fql ", 
  "type": "OAuthException", 
  "code": 604
}

次に、「Web サーバーからの JSON 応答をどのようにフォーマットするかについて、いくつかのルールを定めた仕様」であるJSendがあります。彼らの目標は次のとおりです。

JSON データを提供する Web サービスは数多くありますが、それぞれ独自の方法で応答をフォーマットしています。また、JavaScript フロントエンド用に作成する開発者は、サーバーからデータを通信するための車輪を絶えず再発明しています。このデータを構造化するための一般的なパターンは多数ありますが、名前付けや応答の種類などには一貫性がありません。また、これは、バックエンド開発者とフロントエンド設計者の間の幸福と団結を促進するのに役立ちます.

エラー メッセージの例を次に示します。

{
    "status" : "fail",
    "data" : { "title" : "A title is required" }
}

Facebookと、業界標準のように設定しようとしているこのグループは、あなたの選択#1を選んでいるようです.


報奨金の質問

「だれかが #2 に行って、それを改善したとしたら?」という報奨金のリクエストに応えて、次のようなPragmatic RESTful APIのデザイン パターンがあります。

検証エラーには、フィールドの内訳が必要です。これは、次のように、検証の失敗に固定の最上位エラー コードを使用し、追加のエラー フィールドに詳細なエラーを提供することによって、最もよくモデル化されます。

{
  "code" : 1024,
  "message" : "Validation Failed",
  "errors" : [
    {
      "code" : 5432,
      "field" : "first_name",
      "message" : "First name cannot have fancy characters"
    },
    {
       "code" : 5622,
       "field" : "password",
       "message" : "Password cannot be blank"
    }
  ]
}
于 2015-05-06T14:01:57.733 に答える
3

#2 自分で数回使用しました。#1よりいいですか?それはあなたのAPIが何のために使われているかによると思います。

私が #2 を気に入っているのは、いくつかのテスト コールで API をテストしている開発者が、リクエストで行ったすべてのエラー/間違いの概要を簡単に把握できるためです。そのため、そのリクエストを有効にするためにどのエラー/間違いを修正する必要があるかをすぐに知ることができます。 . エラーを 1 つずつ返す場合 (#1 のように)、リクエストを再試行し続け、今度は有効になることを期待して指を交差させる必要があります。

しかし、私が言ったように、2 番目は開発者にとって非常に便利ですが、その理由は実際にはエンド ユーザーには当てはまりません。エンド ユーザーは通常、それがどのように実装されているかを気にしません。ソフトウェアが 5 つのエラーを返す 1 つの要求を実行しているか、またはそれぞれ 1 つのエラーを返す 5 つの後続の要求を実行しているか。
クライアントで適切に処理されている限り、エンド ユーザーは違いに気付かないはずです。もちろん、それを処理する方法は、クライアントが実際に何であるかによって大きく異なります。

開発のスピードアップに加えて、#2 (本番環境) のもう 1 つの利点は、必要な要求が少なくて済むことです。これにより、もちろんサーバーの負荷が軽減されます。


誰かが#2になり、改善されているかどうかを知りたいので、バウンティを開きました.

確かに改善すべき点はあります。このままでは、ボディ内に省略可能なデータがいくつかあります。

{
  "status": 400,
  "error": {
    "code": 1 //General bad Request code
    "message": "Bad Request",
    "developer_message": "Field validation errors."
    "more_info": "www.api.com/help/errors/1",
    "error_details": {
            0: {
                    "code": 2 // Specific field validation error code
                    "message": "Field \"x\" is missing from the array structure",
                    "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
                    "more_info": "www.api.com/help/errors/2"
                },

            1: {
                (
                    "code": 3 // Specific field validation error code
                    "message": "Incorrect Format for field \"y\"",
                    "developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
                    "more_info": "www.api.com/help/errors/3"
                )
            }
)

HTTP 応答では、ステータス コードは本文ではなくヘッダーに含めるべきです。つまり、"status": 400and"message": "Bad Request"はここでは省略できます。400 は応答のステータス コードである必要があり、400 はBad Requestを意味します。これは HTTP 標準であり、応答で説明する必要はありません。また"developer_message": "Field validation errors."、特定のエラーはそれぞれの個別のエラーに既に含まれているため、重複している可能性があるため、省略できます。

それは去る

{
  "error": {
    "code": 1 //General bad Request code
    "more_info": "www.api.com/help/errors/1",
    "error_details": {
            0: {
                    "code": 2 // Specific field validation error code
                    "message": "Field \"x\" is missing from the array structure",
                    "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
                    "more_info": "www.api.com/help/errors/2"
                },

            1: {
                (
                    "code": 3 // Specific field validation error code
                    "message": "Incorrect Format for field \"y\"",
                    "developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
                    "more_info": "www.api.com/help/errors/3"
                )
            }
)

"code": 1 //General bad Request code
"more_info": "www.api.com/help/errors/1",

この 2 行は、もはや意味を成しません。各エラーには独自のコードと情報リンクがあるため、これらも必要ありません。したがって、これらの行も削除して、

{
  "error": {
    "error_details": {
            0: {
                    "code": 2 // Specific field validation error code
                    "message": "Field \"x\" is missing from the array structure",
                    "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
                    "more_info": "www.api.com/help/errors/2"
                },

            1: {
                (
                    "code": 3 // Specific field validation error code
                    "message": "Incorrect Format for field \"y\"",
                    "developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
                    "more_info": "www.api.com/help/errors/3"
                )
            }
)

400 ステータス コードは、エラーがあったことを既に示して"error": {error details}いるため、エラーがあったことは既にわかっているため、これ以上示す必要はありません。エラーのリストは、単にルート オブジェクトになることができます。

[
    {
        "code": 2//Specificfieldvalidationerrorcode
        "message": "Field \"x\" is missing from the array structure",
        "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
        "more_info": "www.api.com/help/errors/2"
    },
    {
        "code": 3//Specificfieldvalidationerrorcode
        "message": "Incorrect Format for field \"y\"",
        "developer_message": "The field \"y\" must be in the form of \"Y-m-d\"",
        "more_info": "www.api.com/help/errors/3"
    }
]

したがって、本体に残っているのは、単にエラーのリストだけです。

ステータス コードは、応答ヘッダーで指定されます。
詳細は、応答本文で指定されます。

于 2015-04-30T18:09:33.470 に答える
2

私は最近、結果に複数の警告またはエラーを返す Rest API に対して取り組みました。サンプル #2 から始めて、次のように変更します。

{
  "status": 400,
  "results" : null,
  "warnings": {
        0: {
                // Build a warning message here, sample text to show concept
                "code": 1 // Specific field validation error code
                "message": "It is no longer neccessary to put .js on the URL"
           }
  }
  "errors": {
        0: {
                "code": 2 // Specific field validation error code
                "message": "Field \"x\" is missing from the array structure"
                "developer_message": "The request structure must contain the following fields {a,b,c{x,y,z}}",
            },
        1: {
                "code": 3 // Specific field validation error code
                "message": "Incorrect Format for field \"y\"",
                "developer_message": "The field \"y\" must be in the form of \"Y-m-d\""
           }
      }
  }

これにより、応答で必要に応じて複数の警告またはエラーを使用して、結果を提供することができます。

確かに、これには構造の膨張がありますが、開発者がデータを常に同じ構造に戻すための簡単なインターフェイスも提供します。

また、すべてのエラーではなく、APIドキュメント(エラーコードを使用してヘルプを見つける方法)にあるはずの次のアイテムを削除します。

"more_info": "www.api.com/help/errors/2"
"more_info": "www.api.com/help/errors/3"

同じように、メッセージと developer_message の両方が必要かどうかはわかりません。それらは冗長に見え、呼び出し元がデータを正しく提供できなかったときに、API からユーザー エラー メッセージを提供しようとしているかのように見えます。

于 2015-05-06T18:00:27.833 に答える
-2

個人的には、ユーザーにはあまり詳細を伝えず、開発者に必要なエラーをデータベース ログ テーブルまたはシステム ログにダンプします。JSON を使用しており、これは Apache サーバーで最も一般的であり、コードは php である可能性が高いため (ただし、中括弧を含むコード例は、PASCAL に由来する多くの言語である可能性があります。たとえば、C、C# PERL、PHP、 Cシャープ)。php http://php.net/manual/en/function.syslog.phpでまだ方法がわからない場合に、カスタム エラーをシステム ログに出力する方法を次に示します。JSON と CSharp を使用したよりまれな構成の IIS を使用している場合は、同様のことを行う .NET ライブラリもあります。エラーが発生したときにユーザーにあまりにも多くの情報を提供すると、将来、ハッカーが Web サイトを調査する方法を提供することになります。

于 2015-04-30T17:29:17.480 に答える
-4

API は人間向けではありません。したがって、詳細なエラー テキストを返す必要はありません。「パラメーターの欠落」を意味するエラー コードを返すこともできます。よく文書化することを忘れないでください。

于 2015-05-07T09:30:09.633 に答える