GraphQL API с Swift: пошаговый туториал на практике

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

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

Начать курс

Введение: почему GraphQL и Swift — идеальная пара

Современная iOS-разработка немыслима без эффективного взаимодействия с сервером. REST API постепенно уступает место более гибкой и производительной технологии — GraphQL. В этом туториале мы разберём, как интегрировать GraphQL API в Swift-приложение на практике, используя библиотеку Apollo iOS.

GraphQL позволяет запрашивать ровно те данные, которые нужны — ни больше, ни меньше. Для Swift это означает сокращение трафика, ускорение работы и упрощение кода. Мы пройдём полный путь: от настройки проекта до выполнения сложных запросов и мутаций.

1. Настройка проекта и установка Apollo iOS

Первый шаг — подготовка Xcode-проекта и установка зависимостей. Самый удобный способ — через Swift Package Manager.

1.1 Создание нового проекта

Откройте Xcode и создайте новый проект (iOS App или macOS App). Выберите SwiftUI или UIKit — не принципиально. Назовём его GraphQLDemo.

1.2 Добавление Apollo iOS через SPM

  1. В Xcode перейдите: File → Add Package Dependencies...
  2. Вставьте URL репозитория: https://github.com/apollographql/apollo-ios.git
  3. Выберите последнюю стабильную версию и нажмите Add Package.
  4. Убедитесь, что пакет добавлен в таргет вашего приложения.

1.3 Генерация кода схемы

Apollo iOS использует кодогенерацию. Для этого нам нужен файл схемы .graphqls (обычно скачивается с сервера) и файлы запросов .graphql.

// Структура проекта:
// GraphQLDemo/
// ├── GraphQL/
// │   ├── schema.graphqls      // Схема сервера
// │   ├── Queries.graphql      // Запросы
// │   └── Mutations.graphql    // Мутации

После добавления файлов запустите кодогенерацию через терминал:

cd /путь/к/проекту
./Pods/Apollo/apollo-ios-cli --download-schema --endpoint=https://ваш-сервер/graphql
./Pods/Apollo/apollo-ios-cli --generate

Теперь у вас есть сгенерированные Swift-файлы с типами и запросами.

2. Базовый запрос (Query) на Swift

Разберём простейший запрос на получение списка пользователей. Предположим, наша схема содержит тип User с полями id, name, email.

2.1 Создание .graphql файла

В папке GraphQL создайте файл Queries.graphql:

query GetUsers {
  users {
    id
    name
    email
  }
}

2.2 Выполнение запроса в Swift

Сначала инициализируем клиент Apollo:

import Apollo

class NetworkManager {
    static let shared = NetworkManager()
    let apollo: ApolloClient
    
    private init() {
        let url = URL(string: "https://ваш-сервер/graphql")!
        apollo = ApolloClient(url: url)
    }
}

Теперь выполним запрос в любом ViewController или ViewModel:

import SwiftUI

struct UsersView: View {
    @State private var users: [GetUsersQuery.Data.User] = []
    
    var body: some View {
        List(users, id: \.id) { user in
            VStack(alignment: .leading) {
                Text(user.name)
                    .font(.headline)
                Text(user.email)
                    .font(.subheadline)
                    .foregroundColor(.gray)
            }
        }
        .onAppear {
            loadUsers()
        }
    }
    
    private func loadUsers() {
        NetworkManager.shared.apollo.fetch(query: GetUsersQuery()) { result in
            switch result {
            case .success(let graphQLResult):
                if let usersData = graphQLResult.data?.users {
                    self.users = usersData
                }
            case .failure(let error):
                print("Ошибка: \(error.localizedDescription)")
            }
        }
    }
}

Обратите внимание: типы GetUsersQuery и User сгенерированы автоматически. Никакого ручного парсинга JSON!

3. Мутации (Mutation) для изменения данных

Мутации в GraphQL используются для создания, обновления или удаления данных. Рассмотрим пример добавления нового пользователя.

3.1 Определение мутации

Файл Mutations.graphql:

mutation CreateUser($name: String!, $email: String!) {
  createUser(name: $name, email: $email) {
    id
    name
    email
  }
}

3.2 Вызов мутации из Swift

struct AddUserView: View {
    @State private var name = ""
    @State private var email = ""
    @State private var message = ""
    
    var body: some View {
        VStack(spacing: 20) {
            TextField("Имя", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            TextField("Email", text: $email)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            Button("Создать пользователя") {
                createUser()
            }
            Text(message)
                .foregroundColor(.green)
        }
        .padding()
    }
    
    private func createUser() {
        let mutation = CreateUserMutation(name: name, email: email)
        NetworkManager.shared.apollo.perform(mutation: mutation) { result in
            switch result {
            case .success(let graphQLResult):
                if let user = graphQLResult.data?.createUser {
                    self.message = "Пользователь \(user.name) создан!"
                }
            case .failure(let error):
                self.message = "Ошибка: \(error.localizedDescription)"
            }
        }
    }
}

Мутации выполняются методом perform (не fetch). Apollo автоматически обновляет кэш, если это необходимо.

4. Подписки (Subscription) для реального времени

Подписки — одна из сильнейших сторон GraphQL. Они позволяют получать обновления в реальном времени через WebSocket.

4.1 Настройка WebSocket транспорта

Apollo iOS поддерживает WebSocket. Для этого нужно добавить транспорт:

import ApolloWebSocket

extension NetworkManager {
    func setupWebSocket() {
        let webSocketTransport = WebSocketTransport(
            request: URLRequest(url: URL(string: "wss://ваш-сервер/graphql")!)
        )
        let splitNetworkTransport = SplitNetworkTransport(
            uploadingNetworkTransport: apollo.networkTransport,
            webSocketNetworkTransport: webSocketTransport                

Блоги

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