Swift On Server's
Source: Dev.to

Vapor Drawing Backend – Project Overview
A collaborative note‑taking backend built with Vapor (Swift) that supports real‑time collaboration, authentication, and drawing‑strokes persistence.
Tech Stack
- Framework: Vapor 4.115.0
- Database: MongoDB with Fluent ORM
- Authentication: JWT (JSON Web Tokens)
- Real‑time: WebSockets
- Language: Swift 6.0
Features Implemented
1. Authentication System
JWT‑based authentication with user registration and login functionality.
// 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
}
Endpoints
POST /api/v1/auth/register– Register new userPOST /api/v1/auth/login– Login userGET /api/v1/auth/me– Get current user (protected)
2. JWT Middleware
Custom middleware that verifies JWT tokens and protects routes.
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. MongoDB with Fluent ORM
Database configuration using FluentMongoDriver with automatic migrations.
// 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. Notes Management
Full CRUD operations for notes with drawing‑stroke support.
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
}
Endpoints
POST /api/v1/notes– Create noteGET /api/v1/notes– Get all notesGET /api/v1/notes/get/:id– Get single notePUT /api/v1/notes/:id– Update noteDELETE /api/v1/notes/:id– Delete note
5. Real‑time WebSocket Collaboration
WebSocket manager for collaborative editing with note‑session management.
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 Features
- Join/leave note sessions
- Real‑time stroke updates
- Broadcast to all collaborators (excluding sender)
- Personal messaging
Endpoint: WS /api/v1/auth/handleInvite (protected)
6. Note Sharing
Share notes via JWT tokens with external users.
// 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)
Project Structure
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
Getting Started
# Install dependencies
swift package resolve
# Run the server
swift run
# With Docker
docker-compose up
Built with ❤️ using Vapor and Swift.