서버에서의 Swift
Source: Dev.to

Vapor Drawing Backend – 프로젝트 개요
Vapor (Swift)로 구축된 협업 노트 작성 백엔드로, 실시간 협업, 인증, 그리고 drawing‑strokes 영속성을 지원합니다.
기술 스택
- 프레임워크: Vapor 4.115.0
- 데이터베이스: MongoDB with Fluent ORM
- 인증: JWT (JSON Web Tokens)
- 실시간: WebSockets
- 언어: Swift 6.0
Source: …
구현된 기능
1. 인증 시스템
JWT 기반 인증으로 사용자 등록 및 로그인 기능을 제공합니다.
// User model with email and password
final class User: Model, Content, Authenticatable {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "email")
var email: String
@Field(key: "password_hash")
var passwordHash: String
}
엔드포인트
POST /api/v1/auth/register– 새 사용자 등록POST /api/v1/auth/login– 사용자 로그인GET /api/v1/auth/me– 현재 사용자 조회 (보호된 라우트)
2. JWT 미들웨어
JWT 토큰을 검증하고 라우트를 보호하는 커스텀 미들웨어입니다.
struct AuthMiddleware: AsyncMiddleware {
func respond(to request: Request, chainingTo next: any AsyncResponder) async throws -> Response {
let payload: UserToken = try await request.jwt.verify(as: UserToken.self)
guard let user = try await User.find(payload.userID, on: request.db) else {
throw Abort(.unauthorized, reason: "User not found")
}
request.auth.login(user)
return try await next.respond(to: request)
}
}
3. Fluent ORM을 이용한 MongoDB
FluentMongoDriver를 사용한 데이터베이스 설정과 자동 마이그레이션을 제공합니다.
// Configure MongoDB
try app.databases.use(
.mongo(
connectionString: Environment.get("MONGODB_URI") ?? "mongodb://localhost:27017"
),
as: .mongo
)
// Run migrations
app.migrations.add(User.Migration())
app.migrations.add(NotesModel.Migration())
4. 노트 관리
그리기 스트로크 지원을 포함한 노트에 대한 전체 CRUD 작업을 제공합니다.
final class NotesModel: Model, Content {
@Field(key: "title")
var title: String
@Field(key: "strokes")
var strokes: [DrawingStroke]
@Parent(key: "user_id")
var user: User
}
struct DrawingStroke: Codable {
let points: [DrawingPoint]
let color: DrawingColor
let width: Double
let timestamp: Date
}
엔드포인트
POST /api/v1/notes– 노트 생성GET /api/v1/notes– 모든 노트 조회GET /api/v1/notes/get/:id– 단일 노트 조회PUT /api/v1/notes/:id– 노트 업데이트DELETE /api/v1/notes/:id– 노트 삭제
5. 실시간 WebSocket 협업
노트 세션 관리를 위한 WebSocket 매니저로 협업 편집을 지원합니다.
final class WebSocketManager {
private var connections: [UUID: WebSocket] = [:]
private var noteCollaborators: [UUID: Set] = [:]
func joinNoteSession(noteID: UUID, userID: UUID)
func leaveNoteSession(noteID: UUID, userID: UUID)
func broadcastToNote(noteID: UUID, message: String, excludeUserID: UUID?)
}
WebSocket 기능
- 노트 세션 참여/탈퇴
- 실시간 스트로크 업데이트
- 모든 협업자에게 방송 (보낸 사람 제외)
- 개인 메시징
엔드포인트: WS /api/v1/auth/handleInvite (보호된 라우트)
6. 노트 공유
JWT 토큰을 이용해 외부 사용자와 노트를 공유합니다.
// Share token endpoint
GET /api/v1/notes/shared/:shareToken
// Verifies JWT token and returns note
let payload = try await req.jwt.verify(shareToken, as: ShareTokenPayload.self)
프로젝트 구조
Sources/NoterPlayBackend/
├── Controllers/
│ ├── AuthenticationController.swift
│ ├── NotesController.swift
│ └── InviteController.swift
├── Middleware/
│ └── AuthMiddleware.swift
├── Models/
│ ├── User.swift
│ ├── NotesModel.swift
│ ├── UserToken.swift
│ ├── ShareTokenPayload.swift
│ └── InviteModel.swift
├── WSManager/
│ └── WebSocketManager.swift
├── configure.swift
└── routes.swift
시작하기
# Install dependencies
swift package resolve
# Run the server
swift run
# With Docker
docker-compose up
Vapor와 Swift를 사용해 ❤️로 만들었습니다.