Как написать REST API на Swift за 30 минут: руководство для начинающих

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

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

Начать курс

Как написать REST API на Swift за 30 минут: для начинающих

Swift — это не только язык для создания мобильных приложений под iOS и macOS. С появлением фреймворка Vapor разработка серверных приложений на Swift стала доступной и удобной. В этой статье мы покажем, как написать простой REST API на Swift буквально за 30 минут. Вы узнаете основные принципы работы с Vapor, научитесь создавать маршруты, обрабатывать запросы и возвращать JSON-ответы.

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

Что такое REST API и зачем он нужен?

REST (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. REST API позволяет клиентским приложениям (например, iOS-приложению) получать и отправлять данные на сервер через HTTP-запросы.

Основные методы HTTP, используемые в REST:

  • GET — получение данных
  • POST — создание нового ресурса
  • PUT — обновление существующего ресурса
  • DELETE — удаление ресурса

Для нашего примера мы создадим простое API для управления списком задач (Todo List). Оно будет поддерживать все четыре основные операции CRUD (Create, Read, Update, Delete).

Установка Vapor и создание проекта

Vapor — это самый популярный веб-фреймворк для Swift. Для начала работы установите Vapor Toolbox через Homebrew:

brew install vapor

После установки создайте новый проект:

vapor new TodoAPI
cd TodoAPI

Эта команда создаст структуру проекта с уже настроенным сервером. Откройте проект в Xcode:

open Package.swift

В Xcode вы увидите стандартную структуру Vapor-проекта. Основной код находится в папке Sources/App.

Создание модели данных

Для работы с задачами нам нужна модель. Создадим файл Todo.swift в папке Sources/App/Models:

import Vapor
import Fluent

final class Todo: Model, Content {
    static let schema = "todos"
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "title")
    var title: String
    
    @Field(key: "is_completed")
    var isCompleted: Bool
    
    init() {}
    
    init(id: UUID? = nil, title: String, isCompleted: Bool = false) {
        self.id = id
        self.title = title
        self.isCompleted = isCompleted
    }
}

Мы используем Fluent — ORM для Swift, который работает с базами данных. В нашем примере будем использовать SQLite для простоты. Обратите внимание на протокол Content — он позволяет автоматически кодировать/декодировать модель в JSON.

Настройка миграции и базы данных

Теперь создадим миграцию для нашей модели. Добавьте файл CreateTodo.swift в папку Sources/App/Migrations:

import Fluent

struct CreateTodo: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("todos")
            .id()
            .field("title", .string, .required)
            .field("is_completed", .bool, .required)
            .create()
    }
    
    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("todos").delete()
    }
}

В файле configure.swift добавьте регистрацию базы данных и миграции:

import Fluent
import FluentSQLiteDriver

public func configure(_ app: Application) throws {
    app.databases.use(.sqlite(.file("db.sqlite")), as: .sqlite)
    
    app.migrations.add(CreateTodo())
    
    try app.autoMigrate().wait()
    
    try routes(app)
}

Мы используем SQLite как файловую базу данных — это идеально для разработки и тестирования.

Создание маршрутов (Routes)

Теперь самое интересное — реализация API. Откройте файл routes.swift и замените его содержимое:

import Vapor

func routes(_ app: Application) throws {
    let todoController = TodoController()
    
    // Получить все задачи
    app.get("todos") { req async throws -> [Todo] in
        try await Todo.query(on: req.db).all()
    }
    
    // Получить задачу по ID
    app.get("todos", ":id") { req async throws -> Todo in
        guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else {
            throw Abort(.notFound)
        }
        return todo
    }
    
    // Создать новую задачу
    app.post("todos") { req async throws -> Todo in
        let todo = try req.content.decode(Todo.self)
        try await todo.save(on: req.db)
        return todo
    }
    
    // Обновить задачу
    app.put("todos", ":id") { req async throws -> Todo in
        guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else {
            throw Abort(.notFound)
        }
        let updatedTodo = try req.content.decode(Todo.self)
        todo.title = updatedTodo.title
        todo.isCompleted = updatedTodo.isCompleted
        try await todo.save(on: req.db)
        return todo
    }
    
    // Удалить задачу
    app.delete("todos", ":id") { req async throws -> HTTPStatus in
        guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else {
            throw Abort(.notFound)
        }
        try await todo.delete(on: req.db)
        return .noContent
    }
}

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

Тестирование API

Запустите сервер командой в терминале (из папки проекта):

vapor run

Сервер запустится на http://127.0.0.1:8080. Теперь вы можете тестировать API с помощью cURL или любого REST-клиента (например, Postman):

Создать задачу:

curl -X POST http://127.0.0.1:8080/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Изучить Swift", "isCompleted": false}'

Блоги

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