Skip to content

Commit

Permalink
update sbt plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
xuwei-k committed May 12, 2023
1 parent 8829823 commit d86ecab
Show file tree
Hide file tree
Showing 38 changed files with 75 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
distribution: temurin
- uses: actions/checkout@v3
- uses: coursier/cache-action@v6
- run: sbt -v compile "Paradox/paradox"
- run: sbt -v compile paradox
- run: sudo apt-get install tree
- run: tree target
- uses: webfactory/ssh-agent@v0.8.0
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ scalaVersion := "2.13.10"

git.remoteRepo := "git@github.com:unfiltered/unfiltered.github.io.git"

com.typesafe.sbt.SbtGit.GitKeys.gitBranch := Some("master")
com.github.sbt.git.SbtGit.GitKeys.gitBranch := Some("master")

licenses := Seq("MIT" -> url("https://www.opensource.org/licenses/MIT"))

Expand Down
5 changes: 2 additions & 3 deletions project/plugin.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.3")
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.3")
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.10.3")
addSbtPlugin("com.github.sbt" % "sbt-ghpages" % "0.8.0")
addSbtPlugin("com.github.sbt" % "sbt-site-paradox" % "1.5.0")
8 changes: 4 additions & 4 deletions src/paradox/01.md → src/main/paradox/01.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ Now that you have a `scala>` prompt with the `unfiltered-filter` and
`unfiltered-jetty` modules on the classpath, let's have some fun.


@@snip [ ](../main/scala/01.scala) { #example1 }
@@snip [ ](../scala/01.scala) { #example1 }


This filter `echo` would work with any servlet container. We can
use it in a Jetty server right now.

@@snip [ ](../main/scala/01.scala) { #example2 }
@@snip [ ](../scala/01.scala) { #example2 }

The startup message tells you which open port was selected, and by
default it is only listening to requests from 127.0.0.1. So on the
Expand All @@ -75,10 +75,10 @@ not handle the request and Jetty responds with a 404 page.
If we want to handle any request, we could broaden the pattern
matching expression. (Press enter to stop the running server.)

@@snip [ ](../main/scala/01.scala) { #example3 }
@@snip [ ](../scala/01.scala) { #example3 }

Or we could define another filter chain it to the first.

@@snip [ ](../main/scala/01.scala) { #example4 }
@@snip [ ](../scala/01.scala) { #example4 }

Happy now?
12 changes: 6 additions & 6 deletions src/paradox/02.md → src/main/paradox/02.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ without ambiguity.
* An *intent* is a partial function for matching requests.
* A *plan* binds an intent to a particular server interface.

For example, the @extref[`unfiltered.filter.Plan`](unidoc:unfiltered/filter/Plan) trait extends the
For example, the `unfiltered.filter.Plan` trait extends the
`jakarta.servlet.Filter` interface. It declares an abstract `intent`
method for clients to define the intent partial function.

Expand All @@ -19,18 +19,18 @@ method for clients to define the intent partial function.
Looking back at the example on the previous page, you might wonder
where the plan ends and the intent begins.

@@snip [ ](../main/scala/02.scala) { #example1 }
@@snip [ ](../scala/02.scala) { #example1 }

In this case a plan is constructed directly from an anonymous partial
function—that function is the intent. We can define the same plan in
more explicit parts, as is usually necessary in a larger application.

@@snip [ ](../main/scala/02.scala) { #example2 }
@@snip [ ](../scala/02.scala) { #example2 }

Since this kind of plan is an implementation of the servlet filter
interface, we can pass it directly to a servlet container.

@@snip [ ](../main/scala/02.scala) { #example3 }
@@snip [ ](../scala/02.scala) { #example3 }

### Passing on That

Expand All @@ -41,7 +41,7 @@ or it could produce a 404 error from the server.
Unfiltered also supports an explicit mechanism to specify that a
matched request should not be handled by an intent: the `Pass` object.

@@snip [ ](../main/scala/02.scala) { #example4 }
@@snip [ ](../scala/02.scala) { #example4 }

This intent avoids handling anything under `/admin` by matching that
condition and passing on it. There are other ways to achieve the same
Expand All @@ -57,7 +57,7 @@ are undefined.

When you want to combine intents within a single plan, use `onPass`:

@@snip [ ](../main/scala/02.scala) { #example5 }
@@snip [ ](../scala/02.scala) { #example5 }

The `onPass` method is defined implicitly for `PartialFunction` with
the import of the `unfiltered.response._` package. It works like
Expand Down
6 changes: 3 additions & 3 deletions src/paradox/03.md → src/main/paradox/03.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Asynchronous Servlet Filters are using jetty-continuation under the hood which
should provide a general purpose API that will work asynchronously on any servlet-3.0 container, as well as on Jetty 6, 7 or 8
(Continuations will also work in blocking mode with any servlet 2.5 container.)

@@snip [ ](../main/scala/03.scala) { #example1 }
@@snip [ ](../scala/03.scala) { #example1 }

@@@ note
Alternately, `local(8080)` binds to the loopback network interface only.
Expand Down Expand Up @@ -55,10 +55,10 @@ browser interface for a local process. Unfiltered even gives you a
shortcut to open a browser window, if the user is on a 1.6+ JVM that
supports it.

@@snip [ ](../main/scala/03.scala) { #example2 }
@@snip [ ](../scala/03.scala) { #example2 }

#### unfiltered-netty-server

Bootstraps and binds a server for your channel handlers.

@@snip [ ](../main/scala/03.scala) { #example3 }
@@snip [ ](../scala/03.scala) { #example3 }
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions src/paradox/06/a.md → src/main/paradox/06/a.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ objects that work against requests--from path segments to HTTP methods
and headers. Applications use request matchers to define whether and
how they will respond to a request.

@@snip [ ](../../main/scala/06/a.scala) { #example1 }
@@snip [ ](../../scala/06/a.scala) { #example1 }

This case will match GET requests to the path `/record/1`. To match
against path segments, we can nest one additional extractor:

@@snip [ ](../../main/scala/06/a.scala) { #example2 }
@@snip [ ](../../scala/06/a.scala) { #example2 }

This matches any `id` string that is directly under the record
path. The `Seg` extractor object matches against the `String` type and
Expand All @@ -26,7 +26,7 @@ forward-slashes.
The above case clause matches a request to get a record. What about
putting them?

@@snip [ ](../../main/scala/06/a.scala) { #example3 }
@@snip [ ](../../scala/06/a.scala) { #example3 }

Access to the request body generally has side effects, such as the
consumption of a stream that can only be read once. For this reason
Expand All @@ -39,11 +39,11 @@ then read its body into a byte array--on the assumption that its body
will fit into available memory. That aside, a minor annoyance is that
this code introduces some repetition in the matching expression.

@@snip [ ](../../main/scala/06/a.scala) { #example4 }
@@snip [ ](../../scala/06/a.scala) { #example4 }

An alternative is to match first on the path, then on the method:

@@snip [ ](../../main/scala/06/a.scala) { #example5 }
@@snip [ ](../../scala/06/a.scala) { #example5 }

This approach eliminates the duplicated code, but it's important to
recognize that it behaves differently as well. The original intent
Expand Down
14 changes: 7 additions & 7 deletions src/paradox/06/b.md → src/main/paradox/06/b.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Requests are commonly accompanied by named parameters, either in the
[query]: https://en.wikipedia.org/wiki/Query_string
[post]: https://en.wikipedia.org/wiki/POST_%28HTTP%29#Use_for_submitting_web_forms

@@snip [ ](../../main/scala/06/b.scala) { #example1 }
@@snip [ ](../../scala/06/b.scala) { #example1 }

The type of `params` extracted is `Map[String, Seq[String]]`, with a
default value of `Seq.empty`. With this interface, it is always safe
Expand All @@ -24,7 +24,7 @@ For example, the query string `?test&test=3&test` produces the
sequence of strings `"", "3", ""`. You can check this yourself by
querying the plan defined above:

@@snip [ ](../../main/scala/06/b.scala) { #example2 }
@@snip [ ](../../scala/06/b.scala) { #example2 }

### Routing by Parameter

Expand All @@ -36,14 +36,14 @@ need to nest a custom extractor inside `Params`. For this Unfiltered
provides a `Params.Extract` base class:


@@snip [ ](../../main/scala/06/b.scala) { #example3 }
@@snip [ ](../../scala/06/b.scala) { #example3 }

The above extractor will match on the first parameter named "test" in
a request. If no parameters are named test, the pattern does not
match. However, a named parameter with no value would match. We can
exclude this possibility with a richer definition.

@@snip [ ](../../main/scala/06/b.scala) { #example4 }
@@snip [ ](../../scala/06/b.scala) { #example4 }

The second parameter of the `Params.Extract` constructor is a function
`Seq[String] => Option[B]`, with `B` being the type extracted. The
Expand All @@ -60,18 +60,18 @@ When a parameter transformation function fails, `None` is produced and
the extractor does not match for the request. Knowing this, you can
write your own transformation functions using `map` and `filter`.

@@snip [ ](../../main/scala/06/b.scala) { #example5 }
@@snip [ ](../../scala/06/b.scala) { #example5 }

There's also a convenience function to simplify the definition of
transformation *predicates*.

@@snip [ ](../../main/scala/06/b.scala) { #example6 }
@@snip [ ](../../scala/06/b.scala) { #example6 }

Try it all out in this server, which returns 404 unless provided with
a "pos" parameter that is a positive integer, and "neg" that is
negative.

@@snip [ ](../../main/scala/06/b.scala) { #example7 }
@@snip [ ](../../scala/06/b.scala) { #example7 }

@@@ note
The `&` extractor matches when the extractor to its left and right
Expand Down
10 changes: 5 additions & 5 deletions src/paradox/06/c.md → src/main/paradox/06/c.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,31 @@ Unfiltered includes a number of response functions for common response
types. Continuing the "record" example, in some cases we may want to
respond with a particular string:

@@snip [ ](../../main/scala/06/c.scala) { #example1 }
@@snip [ ](../../scala/06/c.scala) { #example1 }

We should also set a status code for this response. Fortunately there
is a predefined function for this too, and response functions are
easily composed. Unfiltered even supplies a chaining combinator `~>`
to make it pretty:

@@snip [ ](../../main/scala/06/c.scala) { #example2 }
@@snip [ ](../../scala/06/c.scala) { #example2 }

If we had some bytes, they would be as easy to serve as strings:

@@snip [ ](../../main/scala/06/c.scala) { #example3 }
@@snip [ ](../../scala/06/c.scala) { #example3 }

Passing or Handling Errors
--------------------------

And finally, for the case of unexpected methods we have a few
choices. One option is to *pass* on the request:

@@snip [ ](../../main/scala/06/c.scala) { #example4 }
@@snip [ ](../../scala/06/c.scala) { #example4 }

The `Pass` response function is a signal for the plan act as if the
request was not defined for this intent. If no other plan responds to
the request, the server may respond with a 404 eror. But we can
improve on that by ensuring that any request to this path that is not
an expected method receives an appropriate response:

@@snip [ ](../../main/scala/06/c.scala) { #example5 }
@@snip [ ](../../scala/06/c.scala) { #example5 }
4 changes: 2 additions & 2 deletions src/paradox/06/d.md → src/main/paradox/06/d.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Using the request matchers and response functions outlined over the
last couple of pages, we have everything we need to build a naive
key-value store.

@@snip [ ](../../main/scala/06/d.scala) { #example1 }
@@snip [ ](../../scala/06/d.scala) { #example1 }

Go ahead and paste that into a @ref:[console](../01.md). Then,
execute the plan with a server, adjusting the port if your system does
not have 8080 available.

@@snip [ ](../../main/scala/06/d.scala) { #example2 }
@@snip [ ](../../scala/06/d.scala) { #example2 }

The method `local`, like `anylocal`, binds only to the loopback
interface, for safety. SillyStore is not quite "web-scale".
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions src/paradox/07/a.md → src/main/paradox/07/a.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ level of abstraction over the core library.
You can define a directive function using familiar request
extractors. Let's start with a raw intent function.

@@snip [ ](../../main/scala/07/a.scala) { #example1 }
@@snip [ ](../../scala/07/a.scala) { #example1 }

You can use curl to inspect the different responses:

Expand All @@ -30,7 +30,7 @@ curl -v http://localhost:8080/
The 404 response page to the second request is not so great. With
directives, we'll do better than that *by default*.

@@snip [ ](../../main/scala/07/a.scala) { #example2 }
@@snip [ ](../../scala/07/a.scala) { #example2 }

And with that you'll see a 406 Not Acceptable response when appropriate.

Expand All @@ -50,7 +50,7 @@ You may have noticed that directives transfer (and enrich) routing
logic from extractors. If your extractors are reduced to the task of
matching against paths alone, you can even eliminate those.

@@snip [ ](../../main/scala/07/a.scala) { #example3 }
@@snip [ ](../../scala/07/a.scala) { #example3 }

It looks pretty different, but remember that here still composes to a
standard Unfiltered intent function.
8 changes: 4 additions & 4 deletions src/paradox/07/b.md → src/main/paradox/07/b.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ different values. Unfiltered's base model for parameters is therefore
a string key to a sequence of string values in the order they were
supplied. This is easy to obtain in a directive.

@@snip [ ](../../main/scala/07/b.scala) { #example1 }
@@snip [ ](../../scala/07/b.scala) { #example1 }

You can try this service with multiple, one, or no parameters.

Expand All @@ -32,11 +32,11 @@ typically, we do have requirements on our input.

Things get more interesting when require parameters to be in a
particular format. From here on out, we'll be working with
*interpreters* in the @extref[`unfiltered.directives.data`](unidoc:unfiltered/directives/data/index)
*interpreters* in the `unfiltered.directives.data`
package. Interpreters define abstract operations on data; we can
produce directives for a particular request parameter with `named`.

@@snip [ ](../../main/scala/07/b.scala) { #example2 }
@@snip [ ](../../scala/07/b.scala) { #example2 }

By testing this service you'll find that all requests to the root path
are accepted, and that the `in` value is bound to an `Option[Int]`. If
Expand All @@ -56,7 +56,7 @@ We can transform an interpreter that ignores failed interpretation
into one that produces a failure response by passing an error handler
to its `fail` method.

@@snip [ ](../../main/scala/07/b.scala) { #example3 }
@@snip [ ](../../scala/07/b.scala) { #example3 }

The error handling function receives both the parameter name and given
value as parameters. This way, a directive used for more than one
Expand Down
4 changes: 2 additions & 2 deletions src/paradox/07/c.md → src/main/paradox/07/c.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parameter of one method that expects an integer. Instead of defining
interpreters inline, as in previous examples, you can define a general
interpreter once and use it many places.

@@snip [ ](../../main/scala/07/c.scala) { #example1 }
@@snip [ ](../../scala/07/c.scala) { #example1 }

In the example above we explicitly reference and apply a single
interpreter to parameters "a" and "b", responding with their sum.
Expand All @@ -28,7 +28,7 @@ using interpreters often and in different applications, naming and
recalling names for various types could become tedious. Let's try it
with an implicit.

@@snip [ ](../../main/scala/07/c.scala) { #example2 }
@@snip [ ](../../scala/07/c.scala) { #example2 }

The first thing you may notice is that `implyIntValue` is a bit
wordier than its predecessor. An implicit interpreter used for request
Expand Down
8 changes: 4 additions & 4 deletions src/paradox/07/d.md → src/main/paradox/07/d.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ for required parameters.
The failure to supply a required parameter must produce an application
defined error response. We'll define a very simple one.

@@snip [ ](../../main/scala/07/d.scala) { #example1 }
@@snip [ ](../../scala/07/d.scala) { #example1 }

The name of the function is not important when used implicitly, but
call it `required` is a good convention since you may also want to use
Expand All @@ -23,7 +23,7 @@ With a required function in scope we can use it with any implicit
interpreters also in scope. The `data.as.String` interpreter is
imported from the `Directives` object, so we can use it immediately.

@@snip [ ](../../main/scala/07/d.scala) { #example2 }
@@snip [ ](../../scala/07/d.scala) { #example2 }

Let's examine the output from this one with curl:

Expand All @@ -43,7 +43,7 @@ chained together in support of both optional and required parameters.
Required is itself an interpreter which unboxes from the `Option`, so
it generally must be the last interpreter in a chain.

@@snip [ ](../../main/scala/07/d.scala) { #example3 }
@@snip [ ](../../scala/07/d.scala) { #example3 }

This service returns the last digit of the required provided
integer. Since we didn't provide a `fail` handler for
Expand All @@ -60,7 +60,7 @@ in is missing
To be more specific, we can supply a failure to the integer
interpreter.

@@snip [ ](../../main/scala/07/d.scala) { #example4 }
@@snip [ ](../../scala/07/d.scala) { #example4 }

Now each failure condition produces a distinct error.

Expand Down
Loading

0 comments on commit d86ecab

Please sign in to comment.