Skip to content

Commit 9d74ac9

Browse files
committed
Generate Vapor project
0 parents  commit 9d74ac9

17 files changed

Lines changed: 496 additions & 0 deletions

File tree

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.build/
2+
.swiftpm/

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Packages
2+
.build
3+
xcuserdata
4+
*.xcodeproj
5+
DerivedData/
6+
.DS_Store
7+
db.sqlite
8+
.swiftpm
9+
.env
10+
.env.*
11+
!.env.example

.vscode/extensions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"recommendations": ["swiftlang.swift-vscode", "Vapor.vapor-vscode"]
3+
}

Dockerfile

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# ================================
2+
# Build image
3+
# ================================
4+
FROM swift:6.0-noble AS build
5+
6+
# Install OS updates
7+
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
8+
&& apt-get -q update \
9+
&& apt-get -q dist-upgrade -y \
10+
&& apt-get install -y libjemalloc-dev
11+
12+
# Set up a build area
13+
WORKDIR /build
14+
15+
# First just resolve dependencies.
16+
# This creates a cached layer that can be reused
17+
# as long as your Package.swift/Package.resolved
18+
# files do not change.
19+
COPY ./Package.* ./
20+
RUN swift package resolve \
21+
$([ -f ./Package.resolved ] && echo "--force-resolved-versions" || true)
22+
23+
# Copy entire repo into container
24+
COPY . .
25+
26+
# Build the application, with optimizations, with static linking, and using jemalloc
27+
# N.B.: The static version of jemalloc is incompatible with the static Swift runtime.
28+
RUN swift build -c release \
29+
--product MessViewBackend \
30+
--static-swift-stdlib \
31+
-Xlinker -ljemalloc
32+
33+
# Switch to the staging area
34+
WORKDIR /staging
35+
36+
# Copy main executable to staging area
37+
RUN cp "$(swift build --package-path /build -c release --show-bin-path)/MessViewBackend" ./
38+
39+
# Copy static swift backtracer binary to staging area
40+
RUN cp "/usr/libexec/swift/linux/swift-backtrace-static" ./
41+
42+
# Copy resources bundled by SPM to staging area
43+
RUN find -L "$(swift build --package-path /build -c release --show-bin-path)/" -regex '.*\.resources$' -exec cp -Ra {} ./ \;
44+
45+
# Copy any resources from the public directory and views directory if the directories exist
46+
# Ensure that by default, neither the directory nor any of its contents are writable.
47+
RUN [ -d /build/Public ] && { mv /build/Public ./Public && chmod -R a-w ./Public; } || true
48+
RUN [ -d /build/Resources ] && { mv /build/Resources ./Resources && chmod -R a-w ./Resources; } || true
49+
50+
# ================================
51+
# Run image
52+
# ================================
53+
FROM ubuntu:noble
54+
55+
# Make sure all system packages are up to date, and install only essential packages.
56+
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
57+
&& apt-get -q update \
58+
&& apt-get -q dist-upgrade -y \
59+
&& apt-get -q install -y \
60+
libjemalloc2 \
61+
ca-certificates \
62+
tzdata \
63+
# If your app or its dependencies import FoundationNetworking, also install `libcurl4`.
64+
# libcurl4 \
65+
# If your app or its dependencies import FoundationXML, also install `libxml2`.
66+
# libxml2 \
67+
&& rm -r /var/lib/apt/lists/*
68+
69+
# Create a vapor user and group with /app as its home directory
70+
RUN useradd --user-group --create-home --system --skel /dev/null --home-dir /app vapor
71+
72+
# Switch to the new home directory
73+
WORKDIR /app
74+
75+
# Copy built executable and any staged resources from builder
76+
COPY --from=build --chown=vapor:vapor /staging /app
77+
78+
# Provide configuration needed by the built-in crash reporter and some sensible default behaviors.
79+
ENV SWIFT_BACKTRACE=enable=yes,sanitize=yes,threads=all,images=all,interactive=no,swift-backtrace=./swift-backtrace-static
80+
81+
# Ensure all further commands run as the vapor user
82+
USER vapor:vapor
83+
84+
# Let Docker bind to port 8080
85+
EXPOSE 8080
86+
87+
# Start the Vapor service when the image is run, default to listening on 8080 in production environment
88+
ENTRYPOINT ["./MessViewBackend"]
89+
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]

Package.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// swift-tools-version:6.0
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "MessViewBackend",
6+
platforms: [
7+
.macOS(.v13)
8+
],
9+
dependencies: [
10+
// 💧 A server-side Swift web framework.
11+
.package(url: "https://github.com/vapor/vapor.git", from: "4.115.0"),
12+
// 🗄 An ORM for SQL and NoSQL databases.
13+
.package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"),
14+
// 🐘 Fluent driver for Postgres.
15+
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.8.0"),
16+
// 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors
17+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
18+
],
19+
targets: [
20+
.executableTarget(
21+
name: "MessViewBackend",
22+
dependencies: [
23+
.product(name: "Fluent", package: "fluent"),
24+
.product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"),
25+
.product(name: "Vapor", package: "vapor"),
26+
.product(name: "NIOCore", package: "swift-nio"),
27+
.product(name: "NIOPosix", package: "swift-nio"),
28+
],
29+
swiftSettings: swiftSettings
30+
),
31+
.testTarget(
32+
name: "MessViewBackendTests",
33+
dependencies: [
34+
.target(name: "MessViewBackend"),
35+
.product(name: "VaporTesting", package: "vapor"),
36+
],
37+
swiftSettings: swiftSettings
38+
)
39+
]
40+
)
41+
42+
var swiftSettings: [SwiftSetting] { [
43+
.enableUpcomingFeature("ExistentialAny"),
44+
] }

Public/.gitkeep

Whitespace-only changes.

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# MessViewBackend
2+
3+
💧 A project built with the Vapor web framework.
4+
5+
## Getting Started
6+
7+
To build the project using the Swift Package Manager, run the following command in the terminal from the root of the project:
8+
```bash
9+
swift build
10+
```
11+
12+
To run the project and start the server, use the following command:
13+
```bash
14+
swift run
15+
```
16+
17+
To execute tests, use the following command:
18+
```bash
19+
swift test
20+
```
21+
22+
### See more
23+
24+
- [Vapor Website](https://vapor.codes)
25+
- [Vapor Documentation](https://docs.vapor.codes)
26+
- [Vapor GitHub](https://github.com/vapor)
27+
- [Vapor Community](https://github.com/vapor-community)

Sources/MessViewBackend/Controllers/.gitkeep

Whitespace-only changes.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Fluent
2+
import Vapor
3+
4+
struct TodoController: RouteCollection {
5+
func boot(routes: any RoutesBuilder) throws {
6+
let todos = routes.grouped("todos")
7+
8+
todos.get(use: self.index)
9+
todos.post(use: self.create)
10+
todos.group(":todoID") { todo in
11+
todo.delete(use: self.delete)
12+
}
13+
}
14+
15+
@Sendable
16+
func index(req: Request) async throws -> [TodoDTO] {
17+
try await Todo.query(on: req.db).all().map { $0.toDTO() }
18+
}
19+
20+
@Sendable
21+
func create(req: Request) async throws -> TodoDTO {
22+
let todo = try req.content.decode(TodoDTO.self).toModel()
23+
24+
try await todo.save(on: req.db)
25+
return todo.toDTO()
26+
}
27+
28+
@Sendable
29+
func delete(req: Request) async throws -> HTTPStatus {
30+
guard let todo = try await Todo.find(req.parameters.get("todoID"), on: req.db) else {
31+
throw Abort(.notFound)
32+
}
33+
34+
try await todo.delete(on: req.db)
35+
return .noContent
36+
}
37+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Fluent
2+
import Vapor
3+
4+
struct TodoDTO: Content {
5+
var id: UUID?
6+
var title: String?
7+
8+
func toModel() -> Todo {
9+
let model = Todo()
10+
11+
model.id = self.id
12+
if let title = self.title {
13+
model.title = title
14+
}
15+
return model
16+
}
17+
}

0 commit comments

Comments
 (0)