0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

APIの連続アクセスを防ぎサーバーに優しくなる

Posted at

目的

アプリを開発する上で、自社や外部のサーバーのAPIを叩くのは当たり前になってますが、連続で叩いちゃって迷惑をかけることもあるかと思います。
APIを叩く側で最初のAPIアクセスから指定した時間をブロックするようなコードを書いてみました。いえ、正確にはChatGPTに書かせてみました。

API実行後、10秒間ブロックします

この実装により、最初のリクエストが送信された後、cooldownPeriodで指定された秒数だけ新たなリクエストがブロックされます。タイマーが完了すると、isRequestAllowedフラグが再びtrueに設定され、リクエストの送信が可能になります。

.swift
import Foundation
import Alamofire

class ApiRateLimiter {
    static let shared = ApiRateLimiter()
    
    private var isRequestAllowed = true
    private var cooldownTimer: Timer?
    private let cooldownPeriod: TimeInterval

    init(cooldownPeriod: TimeInterval = 10.0) { // x秒をデフォルト値とする
        self.cooldownPeriod = cooldownPeriod
    }
    
    func request(_ url: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil, completion: @escaping (Result<Data?, AFError>) -> Void) {
        guard isRequestAllowed else {
            print("Request is blocked due to cooldown.")
            completion(.failure(AFError.explicitlyCancelled))
            return
        }

        isRequestAllowed = false
        // Alamofireを使用してリクエストを実行
        Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).response { response in
            completion(response.result)
        }
        
        // x秒間のクールダウンを開始
        cooldownTimer?.invalidate()
        cooldownTimer = Timer.scheduledTimer(withTimeInterval: cooldownPeriod, repeats: false) { [weak self] _ in
            self?.isRequestAllowed = true
        }
    }
}

あとは、普通に利用するだけですので、APIごとに入れておくとサーバーに優しくなれると思います。

.swift
ApiRateLimiter.shared.request("https://api.example.com/data", method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil) { result in
    switch result {
    case .success(let data):
        print("Received data: \(String(describing: data))")
    case .failure(let error):
        print("Request failed with error: \(error)")
    }
}
0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?