· 7 min read

Getting Started with MongoDB in Swift using MongoKitten

MongoDB is a popular NoSQL database that stores data in flexible, JSON-like documents. MongoKitten provides a Swift-native way to interact with MongoDB, complete with type-safe queries and Codable support.

Learn how to integrate MongoDB with your Swift application using MongoKitten. This tutorial shows you how to set up a connection, work with BSON data, and perform basic database operations.

Setting Up MongoDB

The quickest way to get started with MongoDB is using Docker. Run this command in your terminal:

docker run --name mongodb -d -p 27017:27017 mongo:latest

Adding MongoKitten to Your Project

First, add MongoKitten to your package dependencies:

// Package.swift
let package = Package(
    name: "MyApp",
    dependencies: [
        .package(url: "https://github.com/orlandos-nl/MongoKitten.git", from: "7.0.0")
    ],
    targets: [
        .target(
            name: "MyApp",
            dependencies: [
                .product(name: "MongoKitten", package: "MongoKitten")
            ]
        )
    ]
)

Connecting to MongoDB

Let’s create our first connection:

let db = try await MongoDatabase.connect(to: "mongodb://localhost:27017/social_network")
print("Connected to MongoDB!")
mongokitten-basics.swift:4

Defining Our Models

For our social network, we’ll create a Post model using the Codable protocol:

The ObjectId type is MongoDB’s native unique identifier, similar to a UUID. Every document in MongoDB has an _id field, which must be unique within a collection.

Creating Posts

Let’s create a function to save posts:

func createPost(author: String, content: String) async throws {
    // 1. Create the post
    let post = Post(author: author, content: content)
    
    // 2. Get the posts collection
    let posts = db["posts"]
    
    // 3. Insert the post
    try await posts.insertEncoded(post)
}
mongokitten-basics.swift:25
  1. Create the post as a regular Swift struct

  2. Access the posts MongoCollection, this is similar to a table in a relational database

  3. Call the MongoCollection.insertEncoded(_:writeConcern:) method to insert the post into the database. This method automatically converts the object to BSON and inserts it into the database.

In BSON, all entities are stored as ‘documents’.

Reading Posts

To read posts, we can use MongoKitten’s query API:

// 1. Find all posts
let allPosts = try await db["posts"]
    .find()
    .decode(Post.self)
    .drain()
mongokitten-basics.swift:38

All the methods are chainable, and modify the query. MongoKitten will only execute the query when you call MongoCursor.drain, or iterate over the results of any query.

Before draining the query, you can also call QueryCursor.decode(_:using:) to decode the results into a specific type. This takes the database rows (documents) and decodes them into the specified Decodable type.

The drain function will execute the query and return the results as an array of the specified type.

Filtering Results

MongoKitten supports filtering and sorting on most queries.

// 2. Find posts by a specific author
let authorPosts = try await db["posts"]
    .find("author" == "swift_developer")
    .decode(Post.self)
    .drain()
mongokitten-basics.swift:46

The MongoCollection.find(_:) method returns a FindQueryBuilder, a type of MongoCursor that allows you to chain more methods.

Sorting and Limiting

// 3. Find recent posts, sorted by creation date
let recentPosts = try await db["posts"]
    .find()
    .sort(["createdAt": .descending])
    .limit(10)
    .decode(Post.self)
    .drain()
mongokitten-basics.swift:54

The find method accepts one argument, a filter. By providing the find filter, MongoDB will only return documents that match the filter.

Then, chain the following methods:

Understanding BSON

MongoDB, and by extension MongoKitten, uses BSON (Binary JSON) as its native data format. While MongoKitten handles most BSON conversions automatically through Codable, you can also work with BSON directly:

struct Person: Codable {
    let name: String
    let age: Int
    let tags: [String]
    let active: Bool
}

// Creating a BSON Document manually
let document: Document = [
    "name": "Swift Developer",
    "age": 25,
    "tags": ["swift", "mongodb", "backend"] as Document,
    "active": true
]

// Converting between BSON and Codable
let bsonDocument = try BSONEncoder().encode(document)
let decodedPerson = try BSONDecoder().decode(Person.self, from: bsonDocument)
mongokitten-basics.swift:64

Next Steps

You’ve learned the basics of working with MongoDB using MongoKitten! Here’s what you can explore next:

  • Advanced queries and aggregations

  • Indexing for better performance

  • Working with multiple collections

  • Implementing authentication and authorization

  • Handling relationships between documents

Resources

Related posts

· 8 min read

Realtime MongoDB Updates with ChangeStreams and WebSockets

Learn how to implement real-time updates over WebSockets using ChangeStreams and MongoKitten

Server-Side Swift Conference logo

ServerSide.swift

The talk recordings are live!
See you next year!

Watch the Videos