• Stars
    star
    347
  • Rank 122,129 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 2 years ago
  • Updated 3 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
12,150
star
2

swift-snapshot-testing

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

isowords

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

swift-navigation

Bringing simple and powerful navigation tools to all Swift platforms, inspired by SwiftUI.
Swift
1,950
star
5

swift-dependencies

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

swift-tagged

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

swift-overture

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

pointfreeco

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

episode-code-samples

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

swift-case-paths

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

swift-parsing

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

swift-nonempty

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

swift-custom-dump

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

swift-html

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

combine-schedulers

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

swift-perception

Observable tools, backported.
Swift
536
star
17

swift-identified-collections

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

swift-web

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

swift-prelude

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

swift-validated

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

swift-issue-reporting

Report issues in your application and library code as Xcode runtime warnings, breakpoints, assertions, and do so in a testable manner.
Swift
361
star
22

swift-concurrency-extras

Useful, testable Swift concurrency.
Swift
315
star
23

swift-gen

๐ŸŽฑ Composable, transformable, controllable randomness.
Swift
266
star
24

swift-macro-testing

Magical testing tools for Swift macros.
Swift
263
star
25

swift-clocks

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

syncups

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

swift-enum-properties

๐Ÿค Struct and enum data access in harmony.
Swift
200
star
28

composable-core-location

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

vapor-routing

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

swift-html-vapor

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

swift-playground-templates

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

pointfreeco-server

Point-Free server code.
40
star
33

TrySyncUps

The starting project for our try! Swift 2024 Composable Architecture workshop.
Swift
38
star
34

composable-core-motion

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

swift-boundaries

๐Ÿฃ Functional core, imperative shell.
Swift
28
star
36

swift-quickcheck

๐Ÿ An implementation of QuickCheck in Swift.
Swift
25
star
37

swift-either

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

swift-algebras

Algebraic laws bundled into concrete data types.
20
star
39

swift-parser-printer

โ†”๏ธ Parsing and printing
Swift
15
star
40

swift-html-kitura

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

swiftui-navigation

This package is now Swift Navigation:
Swift
13
star
42

homebrew-swift

Ruby
3
star
43

swift-bugs

3
star
44

Ccmark

Swift
2
star
45

.github

1
star