From 38d9b3a5705da48659c8181eec068ba0ebc2a0db Mon Sep 17 00:00:00 2001 From: Joannis Orlandos Date: Sun, 10 Sep 2017 13:02:52 +0200 Subject: [PATCH] routing docs --- 3.0/docs/routing/async.md | 23 +++++ 3.0/docs/routing/group.md | 111 ++++++++++++++++++++++ 3.0/docs/routing/router.md | 42 ++++++++ 3.0/docs/routing/sync.md | 23 +++++ 3.0/docs/{routing => vapor}/collection.md | 0 3.0/mkdocs.yml | 2 +- 6 files changed, 200 insertions(+), 1 deletion(-) rename 3.0/docs/{routing => vapor}/collection.md (100%) diff --git a/3.0/docs/routing/async.md b/3.0/docs/routing/async.md index e69de29b..fd47b463 100644 --- a/3.0/docs/routing/async.md +++ b/3.0/docs/routing/async.md @@ -0,0 +1,23 @@ +# Asynchronous routing + +The `AsyncRouter` protocol can be applied on top of any router without additional implementation. + +```swift +let router: AsyncRouter = ... +``` + +## Registering a route + +The `on` function on a `AsyncRouter` registers a route to the provided path. The following registers a `GET /hello/world` route. + +It responds with `"Hello world!"` + +```swift +router.on(.get, to: "hello", "world") { request in + return "Hello world!" +} +``` + +The `.get` represents the [Method](../http/method.md) you want to use. `to: "hello", "world"` registers the path `/hello/world`. + +The trailing closure receives a [Request](../http/request.md). The route can throw errors and needs to return a [`ResponseRepresentable`](../vapor/responserepresentable.md) conforming type. diff --git a/3.0/docs/routing/group.md b/3.0/docs/routing/group.md index e69de29b..ed385b74 100644 --- a/3.0/docs/routing/group.md +++ b/3.0/docs/routing/group.md @@ -0,0 +1,111 @@ +# Routing groups + +Routing groups are used to simplify routing. A routing group can contain [middleware](../http/middleware.md) and/or path components. + +## Middleware + +All [Middleware](../http/middleware.md) will be appended inbetween the existing middleware chain and the responder. + +```swift +let group = router.grouped(middleware0, middleware1, middlewareN) + +// This registered route will pass through the following chain +// middleware0 -> middleware1 -> middlewareN -> route +group.on(.get, "hello") { request in + return ... +} +``` + +Closure based syntax also works, when working with route register functions for example. + +```swift +router.group(middleware0, middleware1, middlewareN) { group in + // register routes +} +``` + +Like any closure, you can provide a function here + +```swift +func register(to router: Router) { + // This registered route will pass through the following chain + // middleware0 -> middleware1 -> middlewareN -> route + router.on(.get, "hello") { request in + return ... + } +} + +router.group(middleware0, middleware1, middlewareN, use: register) +``` + +## Path components + +Like the middleware chain, path components will be appended inbetween the existing components and the route. + +```swift +let group = router.grouped("api", "v1") + +// This registered route will be on the following path +// `GET /api/v1/hello` +group.on(.get, "hello") { request in + return ... +} +``` + +The same syntax for grouping is available as with middleware. + +```swift +router.group("api", "v1") { group in + // register routes +} +``` + +Like any closure, you can provide a function here, just like middleware. + +```swift +func register(to router: Router) { + // This registered route will be on the following path + // `GET /api/v1/hello` + router.on(.get, "hello") { request in + return ... + } +} + +router.group("api", "v1", use: register) +``` + +### Parameters + +Parameters inside `Group`s will affect routes. + +```swift +func register(to router: SyncRouter) { + // This registered route will be on the following path + // `GET /api/v1/\(string_here)/echo` + // + // Will return the `string_here` parameter + router.on(.get, "echo") { request in + let string_here = try request.parameters.next(String.self) + + return string_here + } +} + +router.group("api", "v1", String.parameter, use: register) +``` + +**WARNING** + +Using parameters inside a group might have unforeseen effects: + +```swift +let group = router.grouped("api", "v1", String.parameter) + +group.on(.get, String.parameter) { request in + // Expects the route specific string parameter + // Instead gets the grouped string parameter + let parameter = try request.parameters.next(String.self) + + ... +} +``` diff --git a/3.0/docs/routing/router.md b/3.0/docs/routing/router.md index e69de29b..9a005e38 100644 --- a/3.0/docs/routing/router.md +++ b/3.0/docs/routing/router.md @@ -0,0 +1,42 @@ +# Router + +Router is a protocol that you can conform your own routers to. + +## Registering a route + +First, create a [Route](route.md) using a [Method](../http/method.md), path and a responder. + +The following example shows an [async route](async.md) with a constant path. + +```swift +let responder = BasicAsyncResponder { request in + return Future("Hello world") +} + +let route = Route(method: .get, path: [.constant("hello"), .constant("world")], responder: responder) +``` + +The following example shows a [synchronous route](sync.md) with a [Parameter](parameters.md): + +```swift +let responder = BasicSyncResponder { request in + let name = try request.parameters.next(String.self) + return "Hello \(name)" +} + +let route = Route(method: .get, path: [.constant("greet"), .parameter(String.self)], responder: responder) +``` + +## Routing a request through a Router + +Assuming you have a request, like the following example: + +```swift +let request = Request(method: .get, URI(path: "/hello/world")) +``` + +The router should be able to route the [Request](../http/request.md) using + +```swift +let responder = router.route(request: request) +``` diff --git a/3.0/docs/routing/sync.md b/3.0/docs/routing/sync.md index e69de29b..16523332 100644 --- a/3.0/docs/routing/sync.md +++ b/3.0/docs/routing/sync.md @@ -0,0 +1,23 @@ +# Synchronous routing + +The `SyncRouter` protocol can be applied on top of any router without additional implementation. + +```swift +let router: SyncRouter = ... +``` + +## Registering a route + +The `on` function on a `SyncRouter` registers a route to the provided path. The following registers a `GET /hello/world` route. + +It responds with `"Hello world!"` + +```swift +router.on(.get, to: "hello", "world") { request in + return "Hello world!" +} +``` + +The `.get` represents the [Method](../http/method.md) you want to use. `to: "hello", "world"` registers the path `/hello/world`. + +The trailing closure receives a [Request](../http/request.md). The route can throw errors and needs to return a [`ResponseRepresentable`](../vapor/responserepresentable.md) conforming type. diff --git a/3.0/docs/routing/collection.md b/3.0/docs/vapor/collection.md similarity index 100% rename from 3.0/docs/routing/collection.md rename to 3.0/docs/vapor/collection.md diff --git a/3.0/mkdocs.yml b/3.0/mkdocs.yml index e8263569..05a90788 100644 --- a/3.0/mkdocs.yml +++ b/3.0/mkdocs.yml @@ -36,7 +36,6 @@ pages: - Routing: - 'Async': 'routing/async.md' - 'Route Collection': 'routing/collection.md' - - 'Route Group': 'routing/group.md' - 'Parameters': 'routing/parameters.md' - 'Route': 'routing/route.md' - 'Router': 'routing/router.md' @@ -46,6 +45,7 @@ pages: # - '' # - TLS: # - Vapor: +# - 'Route Group': 'routing/group.md' - WebSocket: - 'Basics': - 'Binary': 'websocket/binary-stream.md'