diff --git a/docs/src/pages/routes/README.md b/docs/src/pages/routes/README.md index 6ca2ecf..d9047cf 100644 --- a/docs/src/pages/routes/README.md +++ b/docs/src/pages/routes/README.md @@ -4,11 +4,11 @@ import krop.all.* ``` -Routing handles the HTTP specific details of incoming requests and outgoing responses. Routing can: +Routing handles the HTTP specific details of incoming requests and outgoing responses. The main uses of routes are to: 1. match HTTP requests and extract Scala values; 2. convert Scala values to an HTTP response; and -3. construct clients that do the above in reverse. +3. do the above in reverse in various forms. There are two main abstractions: @@ -33,6 +33,8 @@ val route = Route(Request.get(Path / "user" / Param.int), Response.ok(Entity.tex .handle(userId => s"You asked for the user ${userId.toString}") ``` +This route will match, for example, a GET request to the path `/user/1234` and respond with the string `"You asked for the user 1234"`. + [Request](request.md) and [Response](response.md) have separate pages, so here we'll just discuss the handler. There are three ways to create a handler: using `handle`, `handleIO`, or `passthrough`. Assume the request produces a value of type `A` and the response needs a value of type `B`. Then these three methods have the following meaning: - `handle` is a function `A => B`; @@ -42,7 +44,7 @@ val route = Route(Request.get(Path / "user" / Param.int), Response.ok(Entity.tex ### Type Transformations for Handlers -If you dig into the types produced by `Requests` you will notice a lot of tuple types are used. Here's an example, showing a `Request` producing a `Tuple2`. +If you dig into the types produced by `Request` you will notice a lot of tuple types are used. Here's an example, showing a `Request` producing a `Tuple2`. ```scala mdoc val request = Request.get(Path / Param.int / Param.string) @@ -60,7 +62,17 @@ The conversion between tuples and functions is done by given instances of @:api( ## Reverse Routing -Given a @:api(krop.route.Route) you can construct a hyperlink to that route using the `pathTo` method. Here's an example. +There are three forms of reverse routing: + +* constructing a `String` that corresponds to the path matched by the `Route`; +* constructing a `String` corresponding to the path and query parameters matched by the `Route`; +* constructing a HTTP request that will be matched by the `Route`. + + +### Reverse Routing Path + +Given a @:api(krop.route.Route) you can construct a `String` containing the path to that route using the `pathTo` method. This can be used, for example, to embed hyperlinks to routes in generated HTML. Here's an example. + We first create a @:api(krop.route.Route). ```scala mdoc:silent @@ -96,6 +108,11 @@ twoParams.pathTo(1234, "McBoopy") ``` +### Reverse Routing Path and Query + + + + ## Combining Routes Two or more routes can be combined using the `orElse` method, creating @:api(krop.route.Routes). diff --git a/docs/src/pages/routes/request.md b/docs/src/pages/routes/request.md index 9223fce..aea9269 100644 --- a/docs/src/pages/routes/request.md +++ b/docs/src/pages/routes/request.md @@ -4,17 +4,16 @@ import krop.all.* ``` -A @:api(krop.route.Request) describes a pattern within an HTTP request that a @:api(krop.route.Route) attempts to match. +A @:api(krop.route.Request) describes a pattern within an HTTP request that a @:api(krop.route.Route) attempts to match. It can also create an HTTP request that the `Request` will match. This so-called *reverse routing* allows creating clients that will call an endpoint. A `Request` always matches an HTTP method and a [Path](paths.md). It may match other components of a request as well. It may also extract elements from the path, query parameters, and other parts of the request. These are passed to the `Route` handler. ## Creating Requests -`Requests` are created by calling the method on the `Request` object that corresponds to the HTTP method of interest. For example, `Request.get` for a GET request, `Request.post` for a POST request, and so on. Thesse methods all accept a @:api(krop.route.Path), as described in the [next section](paths.md), which is the only part required path of a `Request` in addition to the HTTP method. - -Builder methods on `Request` can be used to match and extract other parts of an HTTP request. The most common is to extract an HTTP entity, using the `withEntity` method. +`Requests` are created by calling the method on the `Request` object that corresponds to the HTTP method of interest. For example, `Request.get` for a GET request, `Request.post` for a POST request, and so on. Thesse methods all accept a @:api(krop.route.Path), as described in the [next section](paths.md), which is the only required part of a `Request` in addition to the HTTP method. +Builder methods on `Request` can be used to match and extract other parts of an HTTP request. You can either specify headers, and, optionally, a HTTP entity (in that order), just an entity, or neither headers nor entity if you aren't interested in matching parts of the HTTP request beyond the method and path. ## Entities