Vapor Custom headers in the Response using Middleware

We can create a new Middleware to add custom headers to the response:

// CustomHeaderMiddleware.swift 

import Vapor

class CustomHeaderMiddleware: Middleware {
    
    func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        return next.respond(to: request).map { response in
            response.headers.add(name: "Secure", value: "true")
            return response
        }
    }

}

Then we should use this middleware from Configure:

// Configure.swift

let customHeaderMiddleware = CustomHeaderMiddleware()
app.middleware.use(customHeaderMiddleware)

These changes will add the custom header to all the responses from the application.

Read More...

The difference in sql queries for join vs parent relation in Vapor

Parent Relation

The @Parent relation stores a reference to another model’s @ID property. ```swift final class Star: Model { static let schema = “stars”

@ID(key: .id)
var id: UUID? } 

final class Planet: Model { // Example of a parent relation. @Parent(key: “star_id”) var star: Star }

We can eager load the star of planets with the following method:
```swift
Planet.query(on: database).with(\.$star).all().map { planets in
    for planet in planets {
        // `star` is accessible synchronously here 
        // since it has been eager loaded.
        print(planet.star.name)
    }
}

Join

Another method to eager load the star is to join the Star to Planets in the same query:

Read More...

Self referencing table and join query with ModelAlias in Vapor

Self Referencing Table

A self referencing table is a table where the primary key on the table is also defined as a foreign key. Self-referencing table is a table that is a parent and a dependent in the same referential constraint. I. e. in such tables a foreign key constraint can reference columns within the same table.

For example we have a table for categories where we are storing all the categories and sub-categories:

id name parent_id
1 OS  
2 iOS 1

In the above example, the sub-category iOS has a parent_id which is an id of a record in the same table. We can implement the same in Vapor as below:

// Category.swift
@ID(custom: "id")
var id: Int?
@Field(key: "name")
var name: String
@Field(key: "parent_id")
var parentId: Int?
Read More...

Automatic WebSocket pings in Vapor

WebSockets allow for two-way communication between a client and server. Unlike HTTP, which has a request and response pattern, WebSocket peers can send an arbitrary number of messages in either direction. Vapor’s WebSocket API allows you to create both clients and servers that handle messages asynchronously.

We have a messaging application implemented using WebSocket deployed on AWS. We were facing some intermittent connection termination issues. When looked at the issue, we found that Amazon’s Application Load Balancers are configured to shut down connections that haven’t had traffic. There is already an issue reported in the websoclet-kit github repo.

Read More...

JSON encoding/decoding for Vapor Models

Vapor’s content API allows you to easily encode / decode Codable structs to / from HTTP messages. JSON encoding is used by default with out-of-the-box support for URL-Encoded Form and Multipart.

In Vapor 3 we were able to use struct to create Models and using CodingKeys we were able to map the model property name to the DB field name, also we were able to use this to encode/decode the models.

struct User: Model, Content {
    var id: Int?
    var email: String
    var passwordHash: String

    enum CodingKeys: String, CodingKey {
        case id
        case email
        case passwordHash = "password_hash"
    }
}

For this model the JSON data will be:

{
  "id": 1,
  "email": "test@test.com",
  "password_hash": "testPassword"
}
Read More...