Introducción: por qué REST API en Swift es rápido y moderno
El desarrollo de aplicaciones móviles para iOS y macOS requiere no solo una interfaz atractiva, sino también un backend de servidor confiable. REST API (Representational State Transfer) sigue siendo el estándar de facto para el intercambio de datos entre cliente y servidor. Si ya estás escribiendo en Swift para el ecosistema Apple, crear la API en el mismo lenguaje es un paso lógico. Esto permite reutilizar modelos de datos, evitar la duplicación de código e implementar cambios más rápidamente.
En este artículo, mostraremos cómo escribir una REST API completa en Swift utilizando el framework Vapor — el framework web más popular para Swift. Aprenderás a configurar el proyecto, crear rutas, manejar JSON e iniciar el servidor. Todo el proceso tomará no más de 30 minutos. ¿Listo? ¡Vamos allá!
1. Preparación del entorno e instalación de Vapor
Antes de escribir código, asegúrate de tener instaladas las herramientas necesarias. Para trabajar con Vapor necesitarás Swift 5.9 o superior (se recomienda Swift 6). También necesitarás un terminal y un editor de código (Xcode o VS Code).
Instalación de Vapor Toolbox
Vapor Toolbox es una utilidad de línea de comandos que simplifica la creación y gestión de proyectos. Instálala a través de Homebrew:
brew install vaporSi Homebrew no está instalado, descárgalo desde brew.sh. Después de la instalación, verifica la versión:
vapor --versionCreación de un nuevo proyecto
Abre el terminal y ejecuta el comando:
vapor new MyAPI --template=apiLa bandera --template=api crea una estructura básica para REST API sin archivos innecesarios. Navega a la carpeta del proyecto:
cd MyAPIAhora abre el proyecto en Xcode:
open Package.swiftO usa cualquier otro editor. ¡Listo! Tienes una plantilla limpia de Vapor.
2. Estructura básica: modelos, controladores y rutas
Vapor utiliza la arquitectura MVC (Model-View-Controller) adaptada para el desarrollo de servidores. Crearemos una API simple para gestionar una lista de tareas (To-Do list).
Creación del modelo
Un modelo es una estructura que describe los datos. En la carpeta Sources/App/Models/ crea un archivo Todo.swift:
import Fluentimport Vapor
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 }}Usamos Fluent — el ORM de Vapor para trabajar con bases de datos. El modelo se serializa automáticamente a JSON gracias al protocolo Content.
Creación del controlador
El controlador contiene la lógica de procesamiento de solicitudes. Crea un archivo Sources/App/Controllers/TodoController.swift:
import Vaporimport Fluent
struct TodoController: RouteCollection { func boot(routes: RoutesBuilder) throws { let todos = routes.grouped("todos") todos.get(use: index) todos.post(use: create) todos.group(":todoID") { todo in todo.delete(use: delete) } } // GET /todos — obtener todas las tareas func index(req: Request) async throws -> [Todo] { try await Todo.query(on: req.db).all() } // POST /todos — crear una tarea func create(req: Request) async throws -> Todo { let todo = try req.content.decode(Todo.self) try await todo.save(on: req.db) return todo } // DELETE /todos/:id — eliminar una tarea func delete(req: R