swift-vapor-layered-realworld-example-app icon indicating copy to clipboard operation
swift-vapor-layered-realworld-example-app copied to clipboard

Exemplary real world application built with Swift + Vapor. 🐦💧

RealWorld Frontend swift.org Vapor Documentation API Doc My frontend

RealWorld Example App

Vapor codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.

Demo    RealWorld

This codebase was created to demonstrate a fully fledged fullstack application built with Vapor including CRUD operations, authentication, routing, pagination, and more.

We've gone to great lengths to adhere to the Vapor community styleguides & best practices.

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

[toc]

How it works

On local

Precondition

  • Your platform is Linux or Mac.
  • Swift 5.6 or over than is installed.
  • Docker is installed.

Build RealWorld App

$ swift build -c release 

Launch container of MySQL

$ docker-compose up

Generate secret for JWT

$ echo "Your rememberable word" | md5

This can be your favorite method.

Set environment variables

$ export SECRET_FOR_JWT={{ secret for JWT }} \
  MYSQL_HOSTNAME=0.0.0.0 \
  MYSQL_USERNAME=mysqluser \
  MYSQL_PASSWORD=mysqlpass \
  MYSQL_DATABASE=mysqldatabase

This setting values is editable, but it needs to match the setting in docker-compose.yml.

Launch RealWorld App

$ .build/release/realworld serve --hostname 0.0.0.0 --port 8080

Stop servers

By Control + C on launched terminal. Will stop MySQL and App.

On local container (For non-Mac)

Precondition

  • Docker is installed.

Build container for RealWorld App

$ docker build -t realworld:latest .

Create network for local servers

$ docker network create realworld-network

Set environments for MySQL

$ export MYSQL_USERNAME=mysqluser \
  MYSQL_PASSWORD=mysqlpass \
  MYSQL_DATABASE=mysqldatabase \
  MYSQL_ROOTPASS=rootpass

This setting values is editable. Note that the value set at the beginning is recorded.

Launch container of MySQL

$ docker run -d --rm \
    --name mysql-server \
    --network realworld-network \
    --env MYSQL_USER=${MYSQL_USERNAME} \
    --env MYSQL_PASSWORD=${MYSQL_PASSWORD} \
    --env MYSQL_DATABASE=${MYSQL_DATABASE} \
    --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOTPASS} \
    -v ${PWD}/mysql_data:/var/lib/mysql \
    -p 3306:3306 \
    mysql:5.7 \
      --character-set-server=utf8mb4 \
      --collation-server=utf8mb4_unicode_ci

Launch container of RealWorld App

$ docker run -d --rm \
    --name app-server \
    --network realworld-network \
    --env SECRET_FOR_JWT={{ secret for JWT }}\
    --env MYSQL_USERNAME=${MYSQL_USERNAME}\
    --env MYSQL_PASSWORD=${MYSQL_PASSWORD}\
    --env MYSQL_DATABASE=${MYSQL_DATABASE}\
    --env MYSQL_HOSTNAME="mysql-server" \
    -p 8080:80 \
    realworld:latest

Server starting on http://0.0.0.0:80 is displayed. But it opens at http://0.0.0.0:8080 .

Stop containers

$ docker ps
$ docker stop {{ CONTAINER ID or NAME for MySQL }} {{ CONTAINER ID or NAME for RealWorld App }}

On AWS Fargate by pulumi

Precondition

  • You have AWS and pulumi account.
  • AWS and Pulumi CLI is Installed.

Set environments for AWS CLI

$ set +o history # disable record to bash_history 
$ export AWS_ACCESS_KEY_ID={{ Your access key id of AWS account }}
$ export AWS_SECRET_ACCESS_KEY={{ Your access key secret of AWS account }}
$ set -o history
$ clear # flush terminal

Set config to Pulumi.dev.yaml[Optional]

$ pulumi config set mysqlDatabase mysqldatabase
$ pulumi config set --secret mysqlPassword mysqlPass
$ pulumi config set mysqlUser mysqluser
$ pulumi config set secretForJWT {{ secret for JWT }}

Preview pulumi stack

$ cd pulumi
$ pulumi preview

Deploying pulumi stack

$ pulumi up --yes

In this case, the connection settings is listed in pulumi/Pulumi.dev.yaml.

When processing is complete, the host names for MySQL and APP will be displayed.

Outputs:
    appHost  : "svlre-app-listener-*.us-east-1.elb.amazonaws.com"
    mysqlHost: "svlre-mysql-listener-*.elb.us-east-1.amazonaws.com"

Everyone using AWS. I think you know well. Launched resources are expensive💸. Clean up resources when you are done.

Clean up pulumi stack

$ pulumi destroy --yes

⚠️ MySQL storage is volatile.

Getting started

Open Project

Open Package.swift by latest Xcode.
SwiftPM will automatically resolve all the dependencies, and when it is done, you can build.

Set environment variables

Required the first time.
Set the environment variables in menu Product > Scheme > Edit scheme > Run > arguments

key value (example)
HOSTNAME 0.0.0.0
PORT 8080
MYSQL_HOSTNAME 0.0.0.0
MYSQL_USERNAME mysqluser
MYSQL_PASSWORD mysqlpass
MYSQL_DATABASE mysqldatabase
SECRET_FOR_JWT secret

Another way, Put .env on the same directory as the executable binary.
You can find it in the Env directory.

Code entrance

Sources/realworld/main.swift is code of entrance. From here you can follow the entire code!

Connect with Frontend Realworld

Change your Realworld frontend Server host settings. If you are using the Riot version, see here.