• Stars
    star
    373
  • Rank 114,600 (Top 3 %)
  • Language
    Swift
  • License
    BSD 2-Clause "Sim...
  • Created almost 9 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Frank is a DSL for quickly writing web applications in Swift

Frank

Frank is a DSL for quickly writing web applications in Swift with type-safe path routing.

Sources/main.swift
import Frank

// Handle GET requests to path /
get { request in
  return "Hello World"
}

// Handle GET requests to path /users/{username}
get("users", *) { (request, username: String) in
  return "Hello \(username)"
}
Package.swift
import PackageDescription

let package = Package(
  name: "Hello",
  dependencies: [
    .Package(url: "https://github.com/kylef/Frank.git", majorVersion: 0, minor: 4)
  ]
)

Then build, and run it via:

$ swift build --configuration release
$ .build/release/Hello
[2016-01-25 07:13:21 +0000] [25678] [INFO] Listening at http://0.0.0.0:8000 (25678)
[2016-01-25 07:13:21 +0000] [25679] [INFO] Booting worker process with pid: 25679

Check out the full example which can be deployed to Heroku.

Usage

Routes

Routes are constructed with passing your path split by slashes / as separate arguments to the HTTP method (e.g. get, post etc) functions.

For example, to match a path of /users/kyle/followers you can use the following:

get("users", "kyle", "followers") { request in

}

You may pass path components along with wildcard (*) to match variables in paths. The wildcard is a placemarker to annotate where the variable path components are in your path. Frank allows you to use any number of wildcards in any place of the path, allowing you to match all paths.

The wildcards will map directly to parameters in the path and the variables passed into your callback. Wildcard parameters are translated to the type specified in your closure.

// /users/{username}
get("users", *) { (request, username: String) in
  return "Hi \(username)"
}

// /users/{username}/followers
get("users", *, "followers") { (request, username: String) in
  return "\(username) has 5 followers"
}

You may place any type that conforms to ParameterConvertible in your callback, this allows the types to be correctly converted to your type or user will face a 404 since the URL will be invalid.

// /users/{userid}
get("users", *) { (request, userid: Int) in
  return "Hi user with ID: \(userid)"
}
Custom Parameter Types

Wildcard parameters may be of any type that conforms to ParameterConvertible, this allows you to match against custom types providing you conform to ParameterConvertible.

For example, we can create a Status enum which can be Open or Closed which conforms to ParameterConvertible:

enum Status : ParameterConvertible {
  case open
  case closed

  init?(parser: ParameterParser) {
    switch parser.shift() ?? "" {
      case "open":
        self = .open
      case "closed":
        self = .closed
      default:
        return nil
    }
  }
}

get("issues", *) { (request, status: Status) in
  return "Issues using status: \(status)"
}
Adding routes

Routes are matched in the order they are defined. The first route that matches the request is invoked.

get {
  ...
}

put {
  ...
}

patch {
  ...
}

delete {
  ...
}

head {
  ...
}

options {
  ...
}

Return Values

The return value of route blocks takes a type that conforms to the ResponseConvertible protocol, which means you can make any type Response Convertible. For example, you can return a simple string:

get {
  return "Hello World"
}

Return a full response:

get {
  return Response(.ok, headers: ["Custom-Header": "value"])
}

post {
  return Response(.created, content: "User created")
}

Templates

Stencil

You can easily use the Stencil template language with Frank. For example, you can create a convenience function to render templates (called stencil):

import Stencil
import Inquiline
import PathKit


func stencil(path: String, _ context: [String: Any]? = nil) -> ResponseConvertible {
  do {
    let template = try Template(path: Path(path))
    let body = try template.render(Context(dictionary: context))
    return Response(.ok, headers: [("Content-Type", "text/html")], content: body)
  } catch {
    return Response(.internalServerError)
  }
}

Which can easily be called from your route to render a template:

get {
  return stencil("hello.html", ["user": "world"])
}
hello.swift
<html>
  <body>
    Hello {{ user }}!
  </body>
</html>

Nest

Frank is design around the Nest Swift Web Server Gateway Interface, which allows you to use any Nest-compatible web servers. The exposed call function is a Nest compatible application which can be passed to a server of your choice.

import Frank

get {
  return "Custom Server"
}

// Pass "call" to your HTTP server
serve(call)

More Repositories

1

Curassow

Swift HTTP server using the pre-fork worker model
Swift
398
star
2

WebLinking.swift

Swift implementation of web linking (RFC5988)
Swift
156
star
3

swim

Simple build system for the Swift language
Python
122
star
4

CardKit

Model structures for building playable card games in Swift
Swift
109
star
5

podenv

CocoaPods version manager
Shell
100
star
6

Curassow-example-helloworld

Example Swift web application that can be deployed to Heroku
Swift
69
star
7

Ploughman

Ploughman is a Swift tool for running automated tests written in a plain language.
Swift
62
star
8

KFData

Core Data done right for iOS 5+/OS X 10.7+
Objective-C
53
star
9

Expecta-ReactiveCocoa

Expecta matchers for ReactiveCocoa
Objective-C
43
star
10

hpack.swift

HTTP/2 Header Encoding in Swift
Swift
40
star
11

CGFloatType

Provides various methods and functions to deal with CGFloat on 64-bit systems (CGFLOAT_IS_DOUBLE).
Objective-C
38
star
12

fd

Swift file descriptor / socket library
Swift
34
star
13

Starship

A generic API client application for iOS using Hyperdrive.
Swift
28
star
14

Turnstone

Lightweight request routing for Nest
Swift
27
star
15

znc-contrib

A collection of third party modules for ZNC, an IRC bouncer
C++
23
star
16

Requests

Simple synchronous HTTP client in Swift
Swift
22
star
17

znc-bot

A python3 bot (znc module)
Python
21
star
18

spectre-build

Command line tool to build and run tests written using the Spectre Swift BDD testing framework
Swift
20
star
19

lithium

A set of applications for writing a Django website's, it includes a blog, a wiki, and many other useful applications.
Python
16
star
20

RxHyperdrive

RxSwift extensions for Hyperdrive, the generic Swift Web API client
Swift
16
star
21

wol

Small C application to wake a system via the lan
C
15
star
22

znc-xmpp

XMPP module for ZNC
C++
15
star
23

GoReactive

Go library for Functional Reactive Programming, a library for representing and consuming asyncronous data streams with Observables
Go
14
star
24

Mockingdrive

Testing framework for stubbing Hypermedia HTTP requests
Swift
12
star
25

learn-czech

Czech learning notes
11
star
26

BestKit

BestKit makes the Best Swift
Swift
11
star
27

zokket

zokket is an asynchronous socket networking library for python
Python
10
star
28

Frank-example

Example Swift web application using the Frank web framework
Swift
9
star
29

snippt

Easy to use paste site inspired by sprunge and dpaste.de
Python
9
star
30

jsonschema-test

A tool for writing and running tests against a given JSON Schema
Python
9
star
31

Etch

Etch, static website generating in Swift
Swift
8
star
32

Hyperplay

A playground for using Hyperdrive to communicate with a Hypermedia API.
Objective-C
8
star
33

Expecta-Comparison

The missing comparators for Expecta
Objective-C
7
star
34

zmb

A modular ruby-based IRC bot with a powerful but simple plugin interface
Ruby
6
star
35

result.go

Result is a go structure to represent a Result type. It can represent either a success or a failure
Go
6
star
36

bluepaste

API Blueprint paste service
Python
5
star
37

django-projects

django-projects is a Django web application for displaying documentation of a git project via sphinx. This works very much like djangoproject.com, but it is designed for multiple projects. See an example at: http://kylefuller.co.uk/projects/
Python
5
star
38

dnstk

Python DNS toolkit
Python
4
star
39

pyppp

PyPPP is a python implementation of Perfect Paper Passwords a single-use passcode system for multifactor authentication.
Python
4
star
40

lxc

C
3
star
41

geoffrey

Geoffrey is a IRC library written in C. It will eventually evolve into a IRC bot.
C
3
star
42

cod4-server-cfg

Example configuration for a cod4 server
2
star
43

ark

Kyle's Arch Repository
Shell
2
star
44

CommonCrypto

Swift
2
star
45

nginx-config

2
star
46

Refract.swift

A library for interacting with Refract elements.
Swift
2
star
47

repl.py

2
star
48

znc-arch

An arch package containing rc.d scripts for znc
Shell
2
star
49

spec-files

My repository of spec files for Solaris (OpenIndiana)
2
star
50

rack-mlog

rack-mlog is a rack middleware to provide statistics and request logging via a MongoDB collection.
Ruby
2
star
51

KFData.py

Code generator for KFData Core Data
Python
1
star
52

rivr.project

An example rivr project which works on heroku
Python
1
star
53

Podcast

CocoaPods as? Podcast
Ruby
1
star
54

demand-browserid

Python
1
star