📮

Postman製APIをSwiftで叩く時の備忘録

2024/10/16に公開

はじめに

Postmanで作成されたAPIをSwiftで呼び出し、返されたデータをデコードする方法について解説します。この記事では、URLRequestの作成とAPIキーの付与、JSONのデコードなど、APIとの連携に必要な基本的な手順を備忘録として残しました。

環境

  • Xcode16.0 Beta2
  • Swift5.10
  • iOS18.0
  • 標準ライブラリのみ

実装

APIのURLとAPIKeyを確認、URLRequestを作成

APIのアクセス先URLを確認します。認証が必要なAPIの場合はAPIKeyをリクエストのヘッダにつける必要があります。

以下のようにURLRequestを作成します。

let baseURL: URL = URL(string: ...)
let apiKey = "..."
 
let request: URLRequest = {
  var request = URLRequest(url: baseURL)
  request.httpMethod = "GET"

  // APIリクエストの認証に必要なカスタムヘッダを添える
  request.setValue(apiKey, forHTTPHeaderField: "X-API-Key")

  // ついでにキャッシュポリシーも設定しておく
  request.cachePolicy = .returnCacheDataElseLoad
  return request
}

APIを叩いてデータを取得する

URLRequestが作成できたら、今回はURLSessionでAPIを叩きます。👊

let (data, _) = try await URLSession.shared.data(for: request)
let newsItems = try JSONDecoder().decode(ResponseModel.self, from: data)

APIを叩くとDataが手に入ります。
それをSwift側の世界で使えるようにするためにJSONDecoder()Decodableに準拠した型を指定してデコードします。
APIから渡ってくるデータの内容によってResponseModelの型の内容が決まります。
ResponseModelの型がAPI制作者や既にプロジェクトに存在している場合はそれらを参考にすれば良いですが、自分で0から作る必要が出てくる場合、Terminal等から直接APIを叩くことでも確認することができます。

curl -v -H "X-API-Key: your-api-key" https://your.base.url

認証が必要なAPIの場合は-Hオプションとその後にカスタムヘッダを""で囲んで付与します。その後ろにURLをつけて実行します。

curlコマンドを叩き、成功したら返ってきたデータをClaudeに解釈させ、JSONDecoder()でデコードできるstructを作成してもらいました。以下はその一例です。

Claudeにプロンプトを投げてレスポンスモデルを生成してもらう

"hoge": [
        {
            "id": 1,
            "title": "あいうえお",
            "image_url": "https://picsum.photos/200/200",
            "priority": 2
        },
        {
            "id": 2,
            "title": "かきくけこ",
            "image_url": "https://picsum.photos/200/200",
            "priority": 1
        }
    ]

Postmanを叩くとこのbodyが返ってきます。このデータをSwiftで扱えるようにJSONDecodeしたい。レスポンスモデルを出力してください。

出力されたレスポンスモデル

struct HogeResponse: Codable {
    let hoge: [HogeItem]
}

// 各Hoge項目を表す構造体
struct HogeItem: Codable {
    let id: Int
    let title: String
    let imageURL: URL
    let priority: Int

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case imageURL = "image_url"
        case priority
    }
}

全体のコード

struct HogeResponse: Codable {
    let hoge: [HogeItem]
}

// 各Hoge項目を表す構造体
struct HogeItem: Codable {
    let id: Int
    let title: String
    let imageURL: URL
    let priority: Int

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case imageURL = "image_url"
        case priority
    }
}

class HogeService {
  enum Const {
    static let baseURL = URL(string: "...")
    static let apiKey = "..."
  }
  func fetch() async throws -> [HogeItem] {
    var request = URLRequest(url: Const.baseURL)
    request.httpMethod = "GET"
    request.setValue(Const.apiKey, forHTTPHeaderField: "X-API-Key")
    request.cachePolicy = .returnCacheDataElseLoad

    let (data, _) = try await URLSession.shared.data(for: request)
    let hogeItems = try JSONDecoder().decode(HogeResponse.self, from: data)

    return hogeItems.hoge
  }
}

最後に

基本的な部分のみ書きましたが、改善できる箇所はたくさんあると思います。Alamofire等のライブラリを導入したり、APIキーをplistで秘匿したり、Swift-Testingをキャッチアップしてテストを書くなど!

関連

https://picsum.photos/

https://www.postman.com/
https://qiita.com/yasuhiroki/items/a569d3371a66e365316f

https://developer.apple.com/documentation/foundation/urlrequest
https://developer.apple.com/documentation/foundation/urlsession

https://scrapbox.io/armtic/SwiftでPostmanを叩くときの知識

Discussion