Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions frameworks/vapor/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM swift:6.2-jammy AS build
RUN apt-get update && \
apt-get install -y --no-install-recommends libssl-dev zlib1g-dev && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Package.swift .
COPY Sources ./Sources
RUN swift build -c release

FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates libcurl4 libxml2 zlib1g && \
rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/lib/swift/linux/lib*.so /usr/lib/swift/linux/
COPY --from=build /app/.build/release/server /server
EXPOSE 8080
CMD ["/server"]
16 changes: 16 additions & 0 deletions frameworks/vapor/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// swift-tools-version:5.9
import PackageDescription

let package = Package(
name: "server",
platforms: [.macOS(.v13)],
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", from: "4.122.0")
],
targets: [
.executableTarget(
name: "server",
dependencies: [.product(name: "Vapor", package: "vapor")]
)
]
)
26 changes: 26 additions & 0 deletions frameworks/vapor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# vapor

Vapor 4 on SwiftNIO, default configuration.

## Stack

- **Language:** Swift 6.2
- **Framework:** Vapor 4.122
- **Build:** Multi-stage, `ubuntu:22.04` runtime

## Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/pipeline` | GET | Returns `ok` (plain text) |
| `/baseline11` | GET | Sums query parameter values |
| `/baseline11` | POST | Sums query parameters + request body |
| `/json/{count}?m=N` | GET | First `count` dataset items with `total = price * quantity * m` |
| `/upload` | POST | Streams the body and returns the byte count |

## Notes

- Routing and path/query decoding through the Vapor API
- JSON through `Content`, encoded per request by Codable
- Compression through `http.server.configuration.responseCompression`
- `/upload` uses a streaming body so the 20 MB body is never collected
115 changes: 115 additions & 0 deletions frameworks/vapor/Sources/server/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import Foundation
import Vapor

struct Rating: Content {
let score: Int
let count: Int
}

struct DatasetItem: Content {
let id: Int
let name: String
let category: String
let price: Int
let quantity: Int
let active: Bool
let tags: [String]
let rating: Rating
}

struct ProcessedItem: Content {
let id: Int
let name: String
let category: String
let price: Int
let quantity: Int
let active: Bool
let tags: [String]
let rating: Rating
let total: Int
}

struct ProcessResponse: Content {
let items: [ProcessedItem]
let count: Int
}

let datasetPath = Environment.get("DATASET_PATH") ?? "/data/dataset.json"
let dataset: [DatasetItem] = {
guard let data = FileManager.default.contents(atPath: datasetPath),
let items = try? JSONDecoder().decode([DatasetItem].self, from: data)
else {
return []
}
return items
}()

func plain(_ body: String) -> Response {
Response(status: .ok, headers: ["content-type": "text/plain"], body: .init(string: body))
}

func querySum(_ request: Request) -> Int {
guard let query = request.url.query else { return 0 }
var sum = 0
for pair in query.split(separator: "&") {
let parts = pair.split(separator: "=", maxSplits: 1)
if parts.count == 2, let value = Int(parts[1]) {
sum += value
}
}
return sum
}

let app = try await Application.make(.production)
app.logger.logLevel = .error
app.http.server.configuration.hostname = "0.0.0.0"
app.http.server.configuration.port = 8080
app.http.server.configuration.responseCompression = .enabled

app.get("pipeline") { _ in plain("ok") }

app.on(.GET, "baseline11") { request in
plain(String(querySum(request)))
}

app.on(.POST, "baseline11", body: .collect(maxSize: "1mb")) { request -> Response in
var sum = querySum(request)
if let buffer = request.body.data,
let text = buffer.getString(at: buffer.readerIndex, length: buffer.readableBytes),
let value = Int(text.trimmingCharacters(in: .whitespacesAndNewlines)) {
sum += value
}
return plain(String(sum))
}

app.get("json", ":count") { request -> ProcessResponse in
let requested = request.parameters.get("count", as: Int.self) ?? 0
let count = max(0, min(requested, dataset.count))
let m = (try? request.query.get(Int.self, at: "m")) ?? 1

let items = dataset.prefix(count).map { item in
ProcessedItem(
id: item.id,
name: item.name,
category: item.category,
price: item.price,
quantity: item.quantity,
active: item.active,
tags: item.tags,
rating: item.rating,
total: item.price * item.quantity * m
)
}
return ProcessResponse(items: items, count: items.count)
}

app.on(.POST, "upload", body: .stream) { request -> Response in
var size = 0
for try await chunk in request.body {
size += chunk.readableBytes
}
return plain(String(size))
}

try await app.execute()
try await app.asyncShutdown()
19 changes: 19 additions & 0 deletions frameworks/vapor/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"display_name": "vapor",
"language": "Swift",
"type": "flagship",
"mode": "standard",
"engine": "SwiftNIO",
"description": "Vapor 4 on SwiftNIO, default configuration. Routing and parameter decoding through the Vapor API, Codable JSON responses, gzip through the server response compression setting.",
"repo": "https://github.com/vapor/vapor",
"enabled": true,
"tests": [
"baseline",
"pipelined",
"limited-conn",
"json",
"json-comp",
"upload"
],
"maintainers": []
}
Loading