Работа с API на Swift: REST, GraphQL, gRPC – что выбрать в 2025?

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

API на Swift: от теории к реальным запросам

Каждый iOS-разработчик рано или поздно сталкивается с необходимостью общения приложения с сервером. Будь то загрузка ленты новостей, отправка данных формы или стриминг в реальном времени — без API (Application Programming Interface) не обойтись. Но какой протокол выбрать? Классический REST, гибкий GraphQL или сверхскоростной gRPC?

В этой статье мы не просто перечислим плюсы и минусы. Мы разберем работу с API на Swift на реальных примерах, покажем код и дадим практические советы. Вы узнаете, как правильно структурировать сетевой слой, какие библиотеки использовать и когда каждый из подходов становится лучшим выбором.

Если вы пишете на Swift и хотите, чтобы ваше приложение общалось с бэкендом быстро, надежно и красиво — эта статья для вас. Поехали!

REST API на Swift: классика, которая не стареет

REST (Representational State Transfer) — это архитектурный стиль, который использует HTTP-методы (GET, POST, PUT, DELETE) для работы с ресурсами. Большинство публичных API (GitHub, Twitter, Stripe) построены именно на REST. Для Swift-разработчика это означает, что вы будете работать с JSON, URLSession или Alamofire.

Базовый GET-запрос с URLSession

Начнем с самого простого — получения данных. Представим, что нам нужно загрузить список пользователей с JSONPlaceholder:

import Foundation

struct User: Codable {
    let id: Int
    let name: String
    let email: String
}

func fetchUsers() async throws -> [User] {
    let url = URL(string: "https://jsonplaceholder.typicode.com/users")!
    let (data, response) = try await URLSession.shared.data(from: url)
    
    guard let httpResponse = response as? HTTPURLResponse,
          (200...299).contains(httpResponse.statusCode) else {
        throw URLError(.badServerResponse)
    }
    
    return try JSONDecoder().decode([User].self, from: data)
}

Task {
    do {
        let users = try await fetchUsers()
        print("Загружено \(users.count) пользователей")
    } catch {
        print("Ошибка: \(error.localizedDescription)")
    }
}

Обратите внимание на использование async/await — это современный способ работы с асинхронным кодом в Swift. Код стал читаемым и коротким, без замыканий и callback-ов.

POST-запрос с Alamofire

Alamofire — это самая популярная библиотека для работы с сетью на Swift. Она упрощает обработку ошибок, кодирование параметров и загрузку файлов. Вот пример отправки данных:

import Alamofire

struct NewUser: Encodable {
    let name: String
    let email: String
}

AF.request("https://jsonplaceholder.typicode.com/users",
           method: .post,
           parameters: NewUser(name: "Иван", email: "ivan@example.com"),
           encoder: JSONParameterEncoder.default)
    .validate()
    .responseDecodable(of: User.self) { response in
        switch response.result {
        case .success(let user):
            print("Создан пользователь с id: \(user.id)")
        case .failure(let error):
            print("Ошибка: \(error.localizedDescription)")
        }
    }

Совет: Используйте .validate() — это автоматически проверит статус-код и преобразует ошибки HTTP в ошибки Alamofire. Ваш код станет чище, а отладка — проще.

Когда REST — лучший выбор?

  • У вас простое CRUD-приложение (заметки, список задач).
  • API предоставляет фиксированные эндпоинты.
  • Вам не нужна сложная вложенность данных.

GraphQL на Swift: гибкость запросов

GraphQL — это язык запросов, который позволяет клиенту запрашивать ровно те данные, которые нужны. Никакого over-fetching (лишние поля) или under-fetching (нужно несколько запросов). Для Swift есть отличная библиотека Apollo iOS.

Настройка Apollo iOS

Сначала установите пакет через Swift Package Manager. Затем создайте файл схемы (например, schema.graphqls) или используйте кодогенерацию. Пример запроса:

import Apollo

let apollo = ApolloClient(url: URL(string: "https://countries.trevorblades.com")!)

let query = CountriesQuery() // Сгенерированная структура

apollo.fetch(query: query) { result in
    switch result {
    case .success(let graphQLResult):
        if let countries = graphQLResult.data?.countries {
            for country in countries {
                print("\(country.name) - \(country.code)")
            }
        }
    case .failure(let error):
        print("Ошибка GraphQL: \(error)")
    }
}

Ключевая фишка — вы сами решаете, какие поля вернуть. Например, можно запросить только название и код страны, без населения и столицы:

query Countries {
  countries {
    name
    code
  }
}

Это особенно полезно для мобильных приложений, где каждый килобайт трафика на счету.

Мутации (изменение данных)

GraphQL поддерживает не только чтение, но и запись через мутации:

let mutation = AddUserMutation(name: "Мария", email: "maria@example.com")

apollo.perform(mutation: mutation) { result in
    // Обработка результата
}

Когда выбрать GraphQL?

  • У вас сложные, вложенные данные (соцсети, e-commerce).
  • Клиенты (iOS, Android, Web) требуют разные наборы полей.
  • Вы хотите минимизировать количество запросов к серверу.

gRPC на Swift: скорость и типизация

gRPC (Google Remote Procedure Call) — это современный протокол, основанный на HTTP/2 и Protocol Buffers. Он обеспечивает высокую производительность, строгую типизацию и поддержку стриминга. Для Swift есть официальный плагин Swift gRPC.

Как это работает?

Вы описываете сервис и сообщения в .proto файле, затем генерируете Swift-код. Пример определения:

syntax = "proto3";

service UserService {
    rpc GetUser (UserRequest) returns (UserResponse);
    rpc ListUsers (Empty) returns (stream UserResponse); // Серверный стриминг
}

message UserRequest {
    int32 id = 1;
}

message UserResponse {
    int32 id = 1;
    string name = 2;
    string email = 3;
}

После генерации вы получаете сгенерированные классы и протоколы. Клиентский код на Swift выглядит так:

import GRPC
import NIO

let group = PlatformSupport.makeEventLoopGroup(loopCount: 1)
let channel = try GRPCChannelPool.with(
    target: .host("localhost", port: 50051),
    transportSecurity: .plaintext,
    eventLoopGroup: group
)

let client = UserServiceClient(channel: channel)

let request = UserRequest.with { $0.id = 123 }

let response = try client.getUser(request).response.wait()
print("Получен пользователь: \(response.name)")

Стриминг в реальном времени

Одно из главных преимуществ gRPC — поддержка стримов. Например, вы можете получать обновления курса валют или новые

Блоги

Рекомендаций по книгам