Vaporドキュメント学習15:ROUTING-Route Parameters

4105 ワード

従来のWebフレームワークでは、ルーティングパラメータ名とパラメータタイプとして文字列が使用されており、ルーティングエラーの危険性が埋め込まれています.VaporはSwift閉パケットを利用して,より安全で直感的なルーティングパラメータへのアクセス方法を提供する.
Type Safe
パスの一部を置き換えるには、Typeを使用します.
drop.get("users", Int.self) { request, userId in
    return "You requested User #\(userId)"
}
users/:idに一致するルーティングが作成され、:idIntのタイプの下にある.比較として、ルーティングパラメータを手動で判断する方法を示します.
drop.get("users", ":id") { request in
  guard let userId = request.parameters["id"]?.int else {
    throw Abort.badRequest
  }

  return "You requested User #\(userId)"
}

タイプの安全なルーティングは、3行のコードが少ないだけでなく、実行時のエラー(:idスペルエラーなど)を回避することができます.
String Initializable StringInitializableプロトコルに準拠するすべてのタイプは、タイプセキュリティルーティングのパラメータとして使用できます.デフォルトでは、次のタイプが含まれます.
  • String
  • Int
  • Model
  • Stringは最も一般的であり、常に一致することができる.Intは整数に変換できる文字列のみに一致し、Modelは文字列によってデータベースで検出できるモデルのみに一致します.以前の例では、より簡略化できます.
    drop.get("users", User.self) { request, user in
      return "You requested \(user.name)"
    }
    

    ここで指定した識別子は、ユーザーを自動的に検索するために使用されます.たとえば、/users/5Userモデルが要求されると、5と識別されたuserが自動的に検索され、検索されると要求が成功し、閉パッケージが実行されます.そうしないと、ユーザーが検出された例外として放出されます.
    以下はmodelがStringInitializableプロトコルを遵守していない場合の書き方です.
    drop.get("users", Int.self) { request, userId in
      guard let user = try User.find(userId) else {
        throw Abort.notFound
      }
    
        return "You requested User #\(userId)"
    }
    

    タイプの安全なルーティングは、合計6行のコードを1つのルーティングごとに減らすことができます.
    Protocol
    カスタムタイプStringInitializableは簡単です.
    // StringInitializable   
    public protocol StringInitializable {
        init?(from string: String) throws
    }
    

    Modelクラス実装プロトコル方法:
    extension Model {
        public init?(from string: String) throws {
            if let model = try Self.find(string) {
                self = model
            } else {
                return nil
            }
        }
    }
    
    initは、nilに戻ってもよいし、異常を放出してもよい.これにより、カスタム例外を投げ出すことができます.また、nilに戻ってデフォルトの方法で例外を処理することもできます.
    Limits
    現在、タイプの安全なルーティング制限には3つのパラメータしかありません.groupを使用することで、この問題を解決することができます.
    drop.group("v1", "users") { users in
      users.get(User.self, "posts", Post.self) { request, user, post in
        return "Requested \(post.name) for \(user.name)"
      }
    }
    
    /v1/users/:userId/posts/:postIdルーティング要求を処理した結果である.より多くのタイプのセキュリティルーティングを追加するよう呼びかけている場合は、制限数を高めることを考慮することができます.
    Manual
    以上のように、従来のルーティング(非タイプの安全なルーティング)を使用して、特に複雑な状況を処理することができます.
    drop.get("v1", "users", ":userId", "posts", ":postId", "comments", ":commentId") { request in
      let userId = try request.parameters.extract("userId") as Int
      let postId = try request.parameters.extract("postId") as Int
      let commentId = try request.parameters.extract("commentId") as Int
    
      return "You requested comment #\(commentId) for post #\(postId) for user #\(userId)"
    }
    
    request.parameters属性は、URI path符号化のパラメータを抽出するために使用される(例えば、/v1/users/1は、パラメータ:userIdを有し、「1」に等しい).パラメータがクエリの一部として渡される場合(e.g. /v1/search-user?userId=1)、request.data(e.g. let userId = request.data["userId"]?.string)を使用します.
    オプション値を返すことに加えて、要求パラメータは辞書としてアクセスしてもよいし、extract構文を使用してアクセスしてもよい.
    Groups
    パラメータの手動使用はgroupにも適用されます
    let userGroup = drop.grouped("users", ":userId")
    userGroup.get("messages") { req in
        let user = try req.parameters.extract("userId") as User
    }
    

    まとめ:本章では主にルーティングパラメータの設定方法を紹介し、タイプの安全なルーティングは私たちのコードを極めて簡略化することができますが、最大3つのパラメータの制限があります.groupを使用することによって、この問題を解決することができる.複雑な処理の場合、通常のルーティングモードを使用することができます.