• Stars
    star
    321
  • Rank 126,259 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 2 years ago
  • Updated 10 months ago

Reviews

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

Repository Details

A bidirectional router with more type safety and less fuss.

swift-url-routing

A bidirectional URL router with more type safety and less fuss. This library is built with Parsing.


Learn More

This library was discussed in an episode of Point-Free, a video series exploring functional programming and the Swift programming and the Swift language, hosted by Brandon Williams and Stephen Celis.

video poster image

Motivation

URL routing is a ubiquitous problem in both client-side and server-side applications:

  • Clients, such as iOS applications, need to route URLs for deep-linking, which amounts to picking apart a URL in order to figure out where to navigate the user in the app.
  • Servers, such as Vapor applications, also need to pick apart URL requests to figure out what page to serve, but also need to generate valid URLs for linking within the website.

This library provides URL routing function for both client and server applications, and does so in a composable, type-safe manner.

Getting Started

To use the library you first begin with a domain modeling exercise. You model a route enum that represents each URL you want to recognize in your application, and each case of the enum holds the data you want to extract from the URL.

For example, if we had screens in our Books application that represent showing all books, showing a particular book, and searching books, we can model this as an enum:

enum AppRoute {
  case books
  case book(id: Int)
  case searchBooks(query: String, count: Int = 10)
}

Notice that we only encode the data we want to extract from the URL in these cases. There are no details of where this data lives in the URL, such as whether it comes from path parameters, query parameters or POST body data.

Those details are determined by the router, which can be constructed with the tools shipped in this library. Its purpose is to transform an incoming URL into the AppRoute type. For example:

import URLRouting

let appRouter = OneOf {
  // GET /books
  Route(.case(AppRoute.books)) {
    Path { "books" }
  }

  // GET /books/:id
  Route(.case(AppRoute.book(id:))) {
    Path { "books"; Digits() }
  }

  // GET /books/search?query=:query&count=:count
  Route(.case(AppRoute.searchBooks(query:count:))) {
    Path { "books"; "search" }
    Query {
      Field("query")
      Field("count", default: 10) { Digits() }
    }
  }
}

This router describes at a high-level how to pick apart the path components, query parameters, and more from a URL in order to transform it into an AppRoute.

Once this router is defined you can use it to implement deep-linking logic in your application. You can implement a single function that accepts a URL, use the router's match method to transform it into an AppRoute, and then switch on the route to handle each deep link destination:

func handleDeepLink(url: URL) throws {
  switch try appRouter.match(url: url) {
  case .books:
    // navigate to books screen

  case let .book(id: id):
    // navigate to book with id

  case let .searchBooks(query: query, count: count):
    // navigate to search screen with query and count
  }
}

This kind of routing is incredibly useful in client side iOS applications, but it can also be used in server-side applications. Even better, it can automatically transform AppRoute values back into URL's which is handy for linking to various parts of your website:

appRouter.path(for: .searchBooks(query: "Blob Bio"))
// "/books/search?query=Blob%20Bio"
Node.ul(
  books.map { book in
    .li(
      .a(
        .href(appRouter.path(for: .book(id: book.id))),
        book.title
      )
    )
  }
)
<ul>
  <li><a href="/books/1">Blob Autobiography</a></li>
  <li><a href="/books/2">Blobbed around the world</a></li>
  <li><a href="/books/3">Blob's guide to success</a></li>
</ul>

For Vapor bindings to URL Routing, see the Vapor Routing package.

Documentation

The documentation for releases and main are available here:

License

This library is released under the MIT license. See LICENSE for details.

More Repositories

1

swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
Swift
10,990
star
2

swift-snapshot-testing

๐Ÿ“ธ Delightful Swift snapshot testing.
Swift
3,559
star
3

isowords

Open source game built in SwiftUI and the Composable Architecture.
Swift
2,515
star
4

swiftui-navigation

Tools for making SwiftUI navigation simpler, more ergonomic and more precise.
Swift
1,654
star
5

swift-dependencies

A dependency management library inspired by SwiftUI's "environment."
Swift
1,322
star
6

swift-tagged

๐Ÿท A wrapper type for safer, expressive code.
Swift
1,289
star
7

swift-overture

๐ŸŽผ A library for function composition.
Swift
1,115
star
8

pointfreeco

๐ŸŽฌ The source for www.pointfree.co, a video series on functional programming and the Swift programming language.
Swift
1,054
star
9

episode-code-samples

๐Ÿ’พ Point-Free episode code.
Swift
922
star
10

swift-case-paths

๐Ÿงฐ Case paths extends the key path hierarchy to enum cases.
Swift
852
star
11

swift-nonempty

๐ŸŽ A compile-time guarantee that a collection contains a value.
Swift
817
star
12

swift-parsing

A library for turning nebulous data into well-structured data, with a focus on composition, performance, generality, and ergonomics.
Swift
802
star
13

swift-custom-dump

A collection of tools for debugging, diffing, and testing your application's data structures.
Swift
766
star
14

swift-html

๐Ÿ—บ A Swift DSL for type-safe, extensible, and transformable HTML documents.
Swift
726
star
15

combine-schedulers

โฐ A few schedulers that make working with Combine more testable and more versatile.
Swift
671
star
16

swift-web

๐Ÿ•ธ A collection of Swift server-side frameworks for handling HTML, CSS, routing and middleware.
Swift
477
star
17

swift-identified-collections

A library of data structures for working with collections of identifiable elements in an ergonomic, performant way.
Swift
476
star
18

swift-prelude

๐ŸŽถ A collection of types and functions that enhance the Swift language.
Swift
456
star
19

swift-perception

Observable tools, backported.
Swift
399
star
20

swift-validated

๐Ÿ›‚ A result type that accumulates multiple errors.
Swift
389
star
21

swift-concurrency-extras

Useful, testable Swift concurrency.
Swift
267
star
22

swift-gen

๐ŸŽฑ Composable, transformable, controllable randomness.
Swift
262
star
23

swift-clocks

โฐ A few clocks that make working with Swift concurrency more testable and more versatile.
Swift
229
star
24

swift-enum-properties

๐Ÿค Struct and enum data access in harmony.
Swift
198
star
25

xctest-dynamic-overlay

Define XCTest assertion helpers directly in your application and library code.
Swift
197
star
26

swift-macro-testing

Magical testing tools for Swift macros.
Swift
192
star
27

syncups

A rebuild of Appleโ€™s โ€œScrumdingerโ€ application using modern, best practices for SwiftUI development.
Swift
153
star
28

composable-core-location

A library that bridges the Composable Architecture and Core Location.
Swift
100
star
29

vapor-routing

A bidirectional Vapor router with more type safety and less fuss.
Swift
83
star
30

swift-html-vapor

๐Ÿ’ง Vapor plugin for type-safe, transformable HTML views.
Swift
82
star
31

swift-playground-templates

๐Ÿซ A collection of helpful Xcode playground templates.
Makefile
80
star
32

pointfreeco-server

Point-Free server code.
39
star
33

swift-boundaries

๐Ÿฃ Functional core, imperative shell.
Swift
27
star
34

composable-core-motion

A library that bridges the Composable Architecture and Core Motion.
Swift
26
star
35

swift-quickcheck

๐Ÿ An implementation of QuickCheck in Swift.
Swift
24
star
36

swift-algebras

Algebraic laws bundled into concrete data types.
19
star
37

swift-either

For those times you want A or B!
Swift
19
star
38

swift-parser-printer

โ†”๏ธ Parsing and printing
Swift
14
star
39

swift-html-kitura

โ˜๏ธ Kitura plugin for type-safe, transformable HTML views.
Swift
13
star
40

homebrew-swift

Ruby
2
star
41

swift-bugs

2
star
42

Ccmark

Swift
1
star