LoginSignup
5
1
新規開発や新技術の検証、導入にまつわる記事を投稿しよう!

Swift HTTP Typesなるものができたらしい

Last updated at Posted at 2023-07-11

はじめに

2023/7/10にSwift Http Typesなるものができました
本記事では公式ドキュメントの要約とその詳細について執筆していきます。

Swift HTTP Typeでできること

さきにまとめを書いておきます。

  • Swift HTTP TypesではNIOでのURL SessionやFoundationでのHTTPリクエスト、レスポンスといったことが可能
  • 複数フレームワークを使用せずにHTTP通信のやりとりを行えるため、複数フレームワーク間で変換するコストが削減される。
  • HTTP/1.1、HTTP/2、HTTP/3に対応
  • Foundation、Swift NIOとの連携可能

Swift HTTP Typesとは

Swift HTTP typesはHTTPメッセージの構成要素と共通表現について提供するものである。
HTTP RequestとHTTP Responseはクライアント、サーバの両方のユースケースのHTTPメッセージを表している。
複数のプロジェクトでこれを採用することで、より多くのクライアントとサーバ間で共有できるようになり、複数のフレームワークを使用する場合にタイプ間で変換するコストが削減される。

これらの型はHTTP/3やHTTP/2との互換性はもちろん、HTTP/1.1との互換性も維持している。

このパッケージの目標として、SwiftNIOのHTTP requestやHTTP response、FoundationのURL RequestやURL Responseに代わるものとなることを目指す。

このパッケージではあらゆるHTTP通信に適するように設計されており、既存のフレームワークに関連付けられていないため、重複したHTTP抽象化の必要がなくなる。

使用例

HTTPリクエストの核はメソッド、スキーム、権限、パスで構成されている。

let request = HTTPRequest(method: .get, scheme: "https", authority: "www.example.com", path: "/")

FoundationのURLから同じリクエストを作成することもできる

var request = HTTPRequest(method: .get, url: URL(string: "https://www.example.com/")!)

メソッドやプロパティは後からでも変更可能

request.method = .post
request.path = "/upload"

レスポンスの作成も容易に可能

let response = HTTPResponse(status: .ok)

プロパティを使用してヘッダーフィールドにアクセスし、変更もできる

request.headerFields[.userAgent] = "MyApp/1.0"

共通のヘッダーフィールドが組み込まれており、カスタムヘッダーフィールドと値の拡張を簡単にできるため、ビジネスロジックな場面でも容易に使用できる

extension HTTPField.Name {
    static let myCustomHeader = Self("My-Custom-Header")!
}

request.headerFields[.myCustomHeader] = "custom-value"

配列に入った値からもヘッダーフィールドを直接設定できる

request.headerFields[raw: .acceptLanguage] = ["en-US", "zh-Hans-CN"]

ヘッダーフィールドへのアクセスもほぼ同じで、システム定義のフィールド、または独自の拡張機能を使用できる

request.headerFields[.userAgent] // "MyApp/1.0"
request.headerFields[.myCustomHeader] // "custom-value"

request.headerFields[.acceptLanguage] // "en-US, zh-Hans-CN"
request.headerFields[raw: .acceptLanguage] // ["en-US", "zh-Hans-CN"]

Foundationとの連携

URL Sessionを使用すると、“www.example.com”にPOSTでリクエストするための新たなHTTP Requestを作成することも容易である。
このリクエストの"User-Agent"ヘッダーフィールドを設定することはとても直感的なものであり、type systemによる自動補完を提供する。

var request = HTTPRequest(method: .post, url: URL(string: "https://www.example.com/upload")!)
request.headerFields[.userAgent] = "MyApp/1.0"
let (responseBody, response) = try await URLSession.shared.upload(for: request, from: requestBody)
guard response.status == .created else {
    // Handle error
}

Swift NIOとの連携

Swift NIOとの統合は、このパッケージが安定バージョンになると、swift-nio-extrasパッケージで利用できるようになる。
新しいHTTPタイプで使用するNIOチャンネルハンドラーを構成するには、他のチャンネルハンドラーの前に"HTTP2FramePayloadToHTTPServerCodec"を追加する。

NIOTSListenerBootstrap(group: NIOTSEventLoopGroup())
    .childChannelInitializer { channel in
        channel.configureHTTP2Pipeline(mode: .server) { channel in
            channel.pipeline.addHandlers([
                HTTP2FramePayloadToHTTPServerCodec(),
                ExampleChannelHandler()
            ])
        }.map { _ in () }
    }
    .tlsOptions(tlsOptions)

この例のチャンネル実装では、HTTP requestとHTTP responseの両方のタイプを処理する。

final class ExampleChannelHandler: ChannelDuplexHandler {
    typealias InboundIn = HTTPTypeServerRequestPart
    typealias OutboundOut = HTTPTypeServerResponsePart

    func channelRead(context: ChannelHandlerContext, data: NIOAny) {
        switch unwrapInboundIn(data) {
        case .head(let request):
            // Handle request headers
        case .body(let body):
            // Handle request body
        case .end(let trailers):
            // Handle complete request
            let response = HTTPResponse(status: .ok)
            context.write(wrapOutboundOut(.head(response)), promise: nil)
            context.writeAndFlush(wrapOutboundOut(.end(nil)), promise: nil)
        }
    }
}

まとめ

  • Swift HTTP TypesではNIOでのURL SessionやFoundationでのHTTPリクエスト、レスポンスといったことが可能
  • 複数フレームワークを使用せずにHTTP通信のやりとりを行えるため、複数フレームワーク間で変換するコストが削減される。
  • HTTP/1.1、HTTP/2、HTTP/3に対応
  • Foundation、Swift NIOとの連携可能

これを使うことで、いままでより高速なHTTP通信を実現することが出来るかもですね。
いつかFoundation、Swift NIOとの速度比較なども行ってみようと思います。
では、読んでくれてありがとうございました!

5
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1