X-Git-Url: http://nitlanguage.org diff --git a/lib/popcorn/README.md b/lib/popcorn/README.md index 4712faf..50a0de6 100644 --- a/lib/popcorn/README.md +++ b/lib/popcorn/README.md @@ -175,6 +175,17 @@ directory from where you launch your app. If you run the app from another directory, it’s safer to use the absolute path of the directory that you want to serve. +In some cases, you can want to redirect request to static files to a default file +instead of returning a 404 error. +This can be achieved by specifying a default file in the StaticHandler: + +~~~ +app.use("/static/", new StaticHandler("public/", "default.html")) +~~~ + +This way all non-matched queries to the StaticHandler will be answered with the +`default.html` file. + ## Advanced Routing **Routing** refers to the definition of application end points (URIs) and how @@ -353,7 +364,7 @@ The app declared in this example will try to match the routes in this order: ### Route parameters **Route parameters** are variable parts of a route path. They can be used to path -arguments within the URI. +arguments within the URI. Parameters in a route are prefixed with a colon `:` like in `:userId`, `:year`. The following example declares a handler `UserHome` that responds with the `user` @@ -428,6 +439,23 @@ receive a `404 Not found` error. * `res.send()` Send a response of various types. * `res.error()` Set the response status code and send its message as the response body. +## Response cycle + +When the popcorn `App` receives a request, the response cycle is the following: + +1. `pre-middlewares` lookup matching middlewares registered with `use_before(pre_middleware)`: + 1. execute matching middleware by registration order + 2. if a middleware send a response then let the `pre-middlewares` loop continue + with the next middleware +2. `response-handlers` lookup matching handlers registered with `use(handler)`: + 1. execute matching middleware by registration order + 2. if a middleware send a response then stop the `response-handlers` loop + 3. if no hander matches or sends a response, generate a 404 response +3. `post-middlewares` lookup matching handlers registered with `use_after(post_handler)`: + 1. execute matching middleware by registration order + 2. if a middleware send a response then let the `post-middlewares` loop continue + with the next middleware + ## Middlewares ### Overview @@ -465,7 +493,7 @@ end var app = new App -app.use("/*", new MyLogger) +app.use_before("/*", new MyLogger) app.use("/", new HelloHandler) app.listen("localhost", 3000) ~~~ @@ -474,15 +502,16 @@ By using the `MyLogger` handler to the route `/*` we ensure that every requests (even 404 ones) pass through the middleware handler. This handler just prints “Request Logged!” when a request is received. -The order of middleware loading is important: middleware functions that are loaded first are also executed first. -In the above example, `MyLogger` will be executed before `HelloHandler`. +Be default, the order of middleware execution is that are loaded first are also executed first. +To ensure our middleware `MyLogger` will be executed before all the other, we add it +with the `use_before` method. ### Ultra cool, more advanced logger example Next, we’ll create a middleware handler called “LogHandler” that prints the requested uri, the response status and the time it took to Popcorn to process the request. -This example gives a simplified version of the `RequestClock` and `ConsoleLog` middlewares. +This example gives a simplified version of the `RequestClock` and `PopLogger` middlewares. ~~~ import popcorn @@ -519,9 +548,9 @@ class HelloHandler end var app = new App -app.use("/*", new RequestTimeHandler) +app.use_before("/*", new RequestTimeHandler) app.use("/", new HelloHandler) -app.use("/*", new LogHandler) +app.use_after("/*", new LogHandler) app.listen("localhost", 3000) ~~~ @@ -530,9 +559,15 @@ Doing so we can access our data from all handlers that import our module, direct from the `req` parameter. We use the new middleware called `RequestTimeHandler` to initialize the request timer. +Because of the `use_before` method, the `RequestTimeHandler` middleware will be executed +before all the others. + +We then let the `HelloHandler` produce the response. Finally, our `LogHandler` will display a bunch of data and use the request `timer` to display the time it took to process the request. +Because of the `use_after` method, the `LogHandler` middleware will be executed after +all the others. The app now uses the `RequestTimeHandler` middleware for every requests received by the Popcorn app. @@ -549,7 +584,7 @@ Starting with version 0.1, Popcorn provide a set of built-in middleware that can be used to develop your app faster. * `RequestClock`: initializes requests clock. -* `ConsoleLog`: displays resquest and response status in console (can be used with `RequestClock`). +* `PopLogger`: displays resquest and response status in console (can be used with `RequestClock`). * `SessionInit`: initializes requests session (see the `Sessions` section). * `StaticServer`: serves static files (see the `Serving static files with Popcorn` section). * `Router`: a mountable mini-app (see the `Mountable routers` section). @@ -683,7 +718,7 @@ app.listen("localhost", 3000) ## Sessions -**Sessions** can be used thanks to the built-in `SessionMiddleware`. +**Sessions** can be used thanks to the built-in `SessionInit` middleware. Here a simple example of login button that define a value in the `req` session. @@ -712,7 +747,7 @@ class AppLogin end var app = new App -app.use("/*", new SessionInit) +app.use_before("/*", new SessionInit) app.use("/", new AppLogin) app.listen("localhost", 3000) ~~~ @@ -788,7 +823,7 @@ class UserForm end end -var mongo = new MongoClient("mongodb://localhost:27017/") +var mongo = new MongoClient("mongodb://mongo:27017/") var db = mongo.database("mongo_example") var app = new App @@ -808,8 +843,13 @@ to your angular controller: import popcorn var app = new App -app.use("/*", new StaticHandler("my-ng-app/")) +app.use("/*", new StaticHandler("my-ng-app/", "index.html")) app.listen("localhost", 3000) ~~~ +Because the StaticHandler will not find the angular routes as static files, +you must specify the path to the default angular controller. +In this example, the StaticHandler will redirect any unknown requests to the `index.html` +angular controller. + See the examples for a more detailed use case working with a JSON API.