Vapor

Vapor is the most popular Swift web framework. Many people use it happily. It has a highly readable API and is written in the same language you use to interact with it, Swift.

For each library there are different possible integrations that can be created. Some overlap.

Installation

To use MongoKitten 4 with Vapor you will need to have Vapor 2 up and running. First you’ll need to install Swift 3.1 and OpenSSL.

For macOS users this means updating to Xcode 8.3 and running curl https://raw.githubusercontent.com/vapor/vapor/scripts/Utilities/openssl.sh | bash. This will download and run the Vapor OpenSSL setup script which will guide you through any issues.

For Linux (Ubuntu) users you’ll very likely already have OpenSSL set up. You’ll need to install Swift 3.1 from Swift.org

The next step is to update your Package.swift. The dependencies part must at least contain the two packages below.

let package = Package(
  name: "BeerBudzAPI",
  dependencies: [
    .Package(url: "https://github.com/vapor/vapor.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])),
    .Package(url: "https://github.com/OpenKitten/MongoKitten.git", Version(0,0,22)),
  ]
)

After this, the next step is to fetch the new dependencies. This means cleaning up the old ones and fetching the new ones.

swift package update will update the packages folder after which your project should be ready for development.

Xcode users will need to update their Xcode project file using swift package generate-xcodeproj.

MongoKitten

When you’re using one of the above three libraries, one of the types you’ll often use is ObjectId. It is a lightweight unique identifier that is easily representable as a String due to it’s relatively small binary size.

ObjectIds are often expressed as a 24-character hexadecimal string. No wonder that it’s often used in URLs to identify an article, user profile or other database entity.

import Vapor
import BSON

extension ObjectId {
  public init?(from string: String) throws {
    try self.init(string)
  }
}

This makes ObjectId usable within Vapor’s type-safe routes as shown in the example underneath, allowing you to fetch database entities more easily.

import Vapor
import MongoKitten

let drop = Droplet()
let db = Database("mongodb://localhost")

drop.get("articles", ObjectId.init) { request, articleId in
  guard let article = try db["articles"].findOne("_id" == articleId) else {
    // TODO: Article not found
  }

  // TODO: Present article
}

MeowMongo

Like MongoKitten users, MeowMongo users also store their entities in the database, usually with an ObjectId. This means you could apply roughly the same trick on Models.

Assuming the model specified below:

struct Article : Model {
  var id = ObjectId()
  var title: String
  var text: String
  var author: Reference<User>
}

This model doesn’t conform to StringInitializable, yes. But this is easily added in an extension.

extension Article {
  public init?(from string: String) throws {
    guard let me = try Article.findOne("_id" == try ObjectId(string)) else {
      return nil
    }

    self = me
  }
}

From here on you can fetch the Article in your Vapor routes:

import Vapor
import Meow

let drop = Droplet()
Meow.init("mongodb://localhost")

drop.get("articles", Article.init) { request, article in
  // TODO: Present article
}