# README

[![Angel 3 Framework](/files/2LRoJVB36mBKLqzionpQ)](https://github.com/dart-backend/angel)

![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_framework?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/angel_dart/discussion) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/LICENSE)

This is the documentation site for [Angel3](https://github.com/dart-backend/angel), a dart backend framework. It contains tutorials and development guide as well as links to packages of Angel3 framework.

New to Angel3? Read the getting started [Tutorial](https://angel3-docs.dart-backend.com/tutorial/getting-started), and you'll be well on your way.


# Foreword

Angel3 is a fork of archived Angel framework migrated to support null-safety in Dart SDK 2.12.x or later. It is a full-stack Web framework in Dart that aims to streamline development by providing many common features out-of-the-box in a consistent manner. One of the main goal is to enable developers to build both frontend and backend in the same language, Dart. Angel3 framework is designed as a collections of plugins that enable developers to pick and choose the parts needed for their projects. A series of starter templates are also provided for quick start and trial run with Angel3 framework.


# Tutorial


# Getting Started

In this first tutorial, we will:

* Download the `angel3_framework` package from `pub.dev`.
* Launch `Angel3` as backend server.
* Add some basic routing.
* Add a 404 error handler.

The source code for this example can be found at: <https://github.com/dukefirehawk/angel3-examples/tree/master/docs_examples/getting_started>

## Prerequisite

* This tutorial uses command line interface. If you are not well-versed working with it, just copy/paste the code snippets while going through this tutorial.
* The Dart SDK version 2.16 or later is required. Please follow the instructions on the [official dart site](https://dart.dev/get-dart) to download and install it.
* The [`curl`](https://curl.haxx.se/download.html) tool will be used to send requests to the backend server.
* Note that some steps will mention Unix-specific programs, like `vim`. Windows users should instead use `Notepad++`. Alternative programs will be mentioned where relevant.

## Project Setup

The first thing we'll need to do is create a new directory (folder) for our project.

```bash
mkdir hello_angel
cd hello_angel
```

Next, we create a `pubspec.yaml` file, and enter the following contents:

```yaml
name: hello_angel
dependencies:
    angel3_framework: ^6.0.0
```

Now, just run `dart pub get`, which will install the `angel3_framework` library, and its related dependencies:

```bash
Resolving dependencies... (3.3s)
+ angel3_container 6.0.0
+ angel3_framework 6.0.0
+ angel3_http_exception 6.0.0
(... more output omitted)
Changed 33 dependencies!
```

## Launching the Backend Server

`Angel3` can speak different protocols, but more often than not, we'll want it to speak HTTP.

Create a directory named `bin`, and a file within `bin` named `main.dart`.

Your folder structure should now look like this:

```bash
hello_angel
    bin/
        main.dart
    pubspec.yaml
```

Add the following to `bin/main.dart`:

```dart
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';

void main() async {
    var app = Angel();
    var http = AngelHttp(app);
    await http.startServer('localhost', 3000);
}
```

Next, in your terminal, run the command `dart bin/main.dart`. Your server will now be running, and will listen for input until you kill it by entering `Control-C` (the `SIGINT` signal) into the terminal.

Open a new terminal window, and type the following:

```bash
curl localhost:3000 && echo
```

You'll just see a blank line, but the fact that you *didn't see an error* means that the server is indeed listening at port `3000`.

## Adding a Route

By adding *routes* to our server, we can respond to requests sent to different URL's.

Let's a handler at the *root* of our server, and print a simple `Hello, world!` message.

From this point, all new code needs to be added *before* the call to `http.startServer` (or else it will never run).

Add this code to your program:

```dart
app.get('/', (req, res) => res.write('Hello, world!'));
```

`bin/main.dart` should now look like the following:

```dart
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';

main() async {
    var app = Angel();
    var http = AngelHttp(app);
    app.get('/', (req, res) => res.write('Hello, world!'));
    await http.startServer('localhost', 3000);
}
```

(Note that this is the last time the entire file will be pasted, for the sake of brevity.)

Now, if you rerun `curl localhost:3000 && echo`, you'll see the message `Hello, world!` printed to your terminal!

## Route Handlers

Let's break down the line we just added:

```dart
app.get('/', (req, res) => res.write('Hello, world!'));
```

It consists of the following components:

* A call to `app.get`
* A string, `'/'`,
* A closure, taking two parameters: `req` and `res`
* The call `res.write('Hello, world!')`, which is also the return value of the aforementioned closure.

`Angel.get` is one of several methods (`addRoute`, `post`, `patch`, `delete`, `head`, `get`) that can be used to add routes that correspond to [HTTP methods](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) to an `Angel` server instance.

Combined with the path, `'/'`, this signifies that whenever a request is sent to the *root* of our server, which in this case is the URL `http://localhost:3000`, the attached closure should be invoked.

The path is important because it defines the conditions under which code should run. For example, if we were to visit `http://localhost:3000/foo`, we'd just see a blank line printed again, because there is no route mounted corresponding to the path `'/foo'`.

The two parameters, `req` and `res`, hold the types `RequestContext` and `ResponseContext`, respectively. We'll briefly cover these in the next section.

Finally, we call `res.write`, which, as you may have surmised, prints a value to the outgoing HTTP response. That's how we are able to print `Hello, world!`.

## Printing Headers

Just as their names suggest, the `RequestContext` and `ResponseContext` classes are abstractions used to read and write data on the Web.

By reading the property `req.headers`, we can access the [HTTP headers](https://tools.ietf.org/html/rfc2616#section-4.2) sent to us by the client:

```dart
app.get('/headers', (req, res) {
    req.headers.forEach((key, values) {
        res.write('$key=$values');
        res.writeln();
    });
});
```

Run the following:

```bash
curl -H 'X-Foo: bar' -H 'Accept-Language: en-US' \
http://localhost:3000/headers && echo
```

And you'll see output like the following:

```bash
user-agent=[curl/7.54.0]
accept=[*/*]
accept-language=[en-US]
x-foo=[bar]
host=[localhost:3000]
```

## Reading Request Bodies

Web applications very often have users send data upstream, where it is then handled by the server.

`Angel3` has built-in functionality for parsing bodies of three MIME types:

* `application/json`
* `application/x-www-form-urlencoded`
* `multipart/form-data`

(You can also handle others, but that's beyond the scope of this demo.)

So, as long as the user sends data in one of the above forms, we can handle it in the same way.

Add the following route.It will listen on the path `'/greet'` for a `POST` request, and then attempt to parse the incoming reques t body.

Afterwards, it reads the `name` value from the body, and computes a greeting string.

```dart
app.post('/greet', (req, res) async {
    await req.parseBody();

    var name = req.bodyAsMap['name'] as String?;

    if (name == null) {
        throw AngelHttpException.badRequest(message: 'Missing name.');
    } else {
        res.write('Hello, $name!');
    }
});
```

To visit this, enter the following `curl` command:

```bash
curl -X POST -d 'name=Bob' localhost:3000/greet && echo
```

You should see `Hello, Bob!` appear in your terminal.

## Adding an Error Handler

In the previous example, you might have noticed this line:

```dart
throw AngelHttpException.badRequest(message: 'Missing name.');
```

Angel3 handles errors thrown while calling route handlers, preventing your server from crashing. Ultimately, all errors are wrapped in the `AngelHttpException` class, or sent as-is if they are already instances of `AngelHttpException`.

By default, either an HTML page is printed, or a JSON message is displayed (depending on the client's `Accept` header). In many cases, however, you might want to do something else, i.e. rendering an error page, or logging errors through a service like Sentry.

To add your own logic, set the `errorHandler` of your `Angel` instance. It is a function that accepts 3 parameters:

* `AngelHttpException`
* `RequestContext`
* `ResponseContext`

```dart
var oldErrorHandler = app.errorHandler;

app.errorHandler = (e, req, res) {
if (e.statusCode == 400) {
    res.write('Oops! You forgot to include your name.');
} else {
    return oldErrorHandler(e, req, res);
}
```

Note that we kept a reference to the previous error handler, so that existing logic can be reused if the case we wrote for is not handled.

To trigger a `400 Bad Request` and see our error handler in action, run the following:

```bash
curl -H 'Content-Type: application/x-www-form-urlencoded' \
-X POST localhost:3000/greet && echo
```

You will now see `'Oops! You forgot to include your name.'` printed to the console.

## Conclusion

Congratulations on creating your first Angel3 backend server! Hopefully this is just one of many more to come.

The choice is now yours: either continue reading the other guides posted on this site, or tinker around and learn the ropes yourself.

You can find `angel3_*` packages on the [Pub.dev](https://pub.dev) site, and read the documentation found in their respective `README` files.

Don't forget that for discussion and support, you can either file a Github issue, or join the [Gitter chat](https://gitter.im/angel_dart/discussion)


# Minimal Setup

It's very easy to setup a bare-bones Angel3 server.

Any Dart project needs a project file, called `pubspec.yaml`. This file almost always contains a `dependencies` section, where you will install the Angel3 framework libraries.

```yaml
dependencies:
    angel3_framework: ^6.0.0
```

You might also want to install packages such as `angel3_static`, `angel3_cache`, `angel3_jael`, and `angel3_cors`.

Next, run `pub get` on the command line, or in your IDE if it has Dart support. This will install the framework and all of its dependencies.

Next, create a file, `bin/main.dart`. Put this code in it:

```dart
import 'dart:io';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';

void main() async {
  var app = Angel();
  var http = AngelHttp(app);

  app.get("/", (req, res) => "Hello, world!");

  var server = await http.startServer();
  print("Angel server listening at ${http.uri}");
}
```

The specifics are not that important, but there are a few important calls here:

* `var app = Angel()` - The base Angel3 server is a simple class, and we need an instance of it to run our server. The name `app` is a convention adopted from Express. In general, call an Angel3 instance `app`. This has no effect on functionality, but it makes it easier for other developers to understand your code.
* `app.get("/", (req, res) => "Hello, world!");` - This is a [route](https://github.com/dukefirehawk/angel3-guide/blob/master/tutorial/basic-routing.md), and tells our server to respond to all GET requests at our server root with `"Hello, world!"`. The response will automatically be encoded as JSON. Head over to the [Basic Routing](https://github.com/dukefirehawk/angel3-guide/blob/master/tutorial/basic-routing.md) tutorial to learn about routes, and how they work.
* `await http.startServer(...)` - This asynchronous call is what actually starts the server listening. Without it, your application won't be accessible over HTTP (as it won't ever listen for requests).

That's it! Your server is ready to serve requests. You can easily start it from the command line like this:

```dart
dart bin/main.dart
```


# Command Line Interface


# Setup

Installing `angel3_cli` installs a command line dart application in your local environment. Executed from the terminal, it provides access to a set of useful commands for working with [Angel3](https://pub.dev/packages/angel3_framework). The `--help` option gives more information about the available options.

## Installation

* Prerequisite: [Dart SDK](https://www.dartlang.org/downloads/) must be installed
* Open a terminal screen and run the following command.

  ```bash
    dart pub global activate angel3_cli
  ```

### Creating a New Project

* Creating a new project, `hello`, in the current directory, run:

  ```bash
    angel3 init hello
  ```
* Initializing a project within a directory, `hello`, run:

  ```bash
    angel3 init
  ```
* Follows the instructions given to complete setting up the new project. Choose from one of the available [Angel3 templates](https://github.com/dukefirehawk/boilerplates) to best represents what you would like your backend server to do. A well structured project will be generated and ready for development.

### Starting Backend Server

* Running the server in development mode:

  ```bash
    # Use the `--observe` flag to enable hot reloading in Angel3.
    dart --observe bin/dev.dart
  ```
* Running the server in production mode:

  ```bash
    dart bin/prod.dart
  ```


# Templates and Views


# Server Side Rendered Views

* [Rendering Views](#rendering-views)
  * [Example](#example)
  * [`ViewGenerator` typedef](#viewgenerator)

## Rendering Views

Just like `res.render` in Express, Angel's `ResponseContext` exposes a `Future` called `render`. This invokes whichever function is assigned to your server's `viewGenerator`.

There is a Mustache templating plug-in for Angel available: <https://github.com/dukefirehawk/angel/tree/master/packages/mustache>

There is also [Jael](https://github.com/dukefirehawk/angel/tree/master/packages/jael3), one of the few actively-developed HTML templating engines for Dart.

Angel support for Jael is provided through [`package:angel3_jael`](https://github.com/dukefirehawk/angel/tree/master/packages/angel_jael).

Another is Jinja2, which was recently ported by to Dart by [Olzhas Suleimen](https://github.com/ykmnkmi/jinja.dart).

Angel support for Jinja2 can be found here: <https://github.com/dukefirehawk/angel/tree/master/packages/angel_jinja>

### Example

```dart
app.get('/view', (req, res) async => await res.render('hello', {'locals': ['foo', 'bar']});
```

### ViewGenerator

Angel declares the following typedef:

```dart
/// A function that asynchronously generates a view from the given path and data.
typedef Future<String> ViewGenerator(String path, [Map data]);
```

A templating plug-in can assign one of these to `app.viewGenerator` to set itself up:

```dart
import 'dart:io';
import 'package:angel3_framework/angel3_framework.dart';

Future<void> plugin(Angel app) async {
  app.viewGenerator = (String path, [Map data]) async {
    return "Requested view $path with locals: $data";
  };
}

void main() async {
  var app = Angel();
  await app.configure(plugin);
  await app.startServer();
}
```


# JAEL3


# About

**Jael3** is a simple, yet powerful, server-side HTML templating engine for Dart. Although it can be used in any application, it comes with first-class support for the [Angel3](https://github.com/dukefirehawk/angel) framework.

Though its syntax is but a superset of HTML, it supports features such as:

* **Custom elements**
* Loops
* Conditionals
* Template inheritance
* Block scoping
* `switch` syntax
* Interpolation of any Dart expression

## Small Example

```html
<!-- layout.jl -->
<html>
    <head>
        <title>{{ title }} - My App</title>
    </head>
    <body>
        <block name="content"></block>
        <div class="footer">
          <!-- Footer content... -->
        </div>
    </body>
</html>

<!-- user-info.jl -->
<element name="user-info">
    <img src=user.avatar ?? "http://example.com/img/default-avatar">
    Hello, {{ user.name }}!
</element>

<!-- hello.jl -->
<extend src="layout.jl">
  <include src="user-info.jl" />
  <block name="content">
    <user-info @user=getCurrentlyAuthenticatedUserSomehow() />
  </block>
</extend>
```

The typical flow of a full-stack Dart application is to develop two separate apps:

* The server
* The client, an entire SPA

However, the truth is, many projects will never reach great scale, or are not extensive Web applications, and thus do not need the added complexity of an SPA. In such a case, creating an SPA will consume much excess time.

Jael allows developers to create a frontend for their application without having to worry about push state, increased development time, or having to find complex ways to achieve "server-side rendering."

Rather than forcing you to learn an entire DSL, Jael's syntax is one you already know - HTML. All directives take the form of HTML elements, and are applied either by the preprocessor or at runtime. Jael's AST is simple to patch, so it is relatively straightforward to patch it to add new features.

Jael can easily be used in any application with the following two packages:

* `package:jael3`
* `package:jael3_preprocessor`

However, [Angel3](https://github.com/dukefirehawk/angel) users only need install `package:angel3_jael` to include templating in their server-side applications. One of Angel3's goals is to make Web development faster, and having a tool like Jael at its disposal only brings that goal even closer to fruition.


# Basics

* [Basic](#basic)
  * [Interpolation](#interpolation)
  * [Attributes](#attributes)
    * [Attribute Values](#attribute-values)
    * [Quoted Attribute Names](#quoted-attribute-names)
    * [Unescaped Attributes](#unescaped-attributes)

Jael syntax is a superset of HTML. The following is valid both in HTML and Jael:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <h1>Hello!</h1>
  </body>
</html>
```

However, Jael adds two major changes.

## Interpolation

Firstly, text blocks can contain *interpolations*, which are merely Dart expression contained in double curly braces (`{{ }}`). The value within the braces, once evaluated will be HTML escaped, to prevent XSS. To achieve unescaped output, append a hyphen (`-`) to the first brace (`{{- }}`).

```html
<div>
  {{ user.name }}
</div>

<!-- Do not HTML escape this: -->
<div>
  {{- raw.data.will.not.be('escaped') }}
</div>
```

## Attributes

Secondly, whereas in HTML, the values of attributes can only be strings, Jael allows for their values to be any Dart expression:

```html
<img src=profile.avatar ?? "http://example.com/img/avatars/default.png">
<a class=['btn', 'ban-default', 'btn-lg']>Link</a>
<p style={'color': 'red'}></p>
```

### Attribute Values

Values are handled as such:

* Maps: Serialized as though they were `style` attributes.
* Iterables: Joined by a space, like `class` attributes.
* Anything else: `toString()` is invoked.

### Quoted Attribute Names

In case the name of your attribute is not a valid Dart identifier, you can wrap it with quotes, and it will still be processed as per normal:

```html
<button "(click)"="myEventHandler($event)" />
```

### Unescaped Attributes

These will also be HTML escaped; however, you can replace `=` with `!=` to print unescaped text:

```html
<img src!="<SCARY XSS STRING BEWARE!!!>" />
```


# Custom Elements

HTML is good for its purpose, because each element (ex. `div`, `a`, `ul`), has its own purpose, and when invoked, reproduces specific functionality.

The goal of proposals like Web Components, and frameworks like React, Vue, and Angular, is to let developers create custom components that encapsulate data and can be called to reproduce specific output.

Jael also supports defining elements; in fact, they are analogous to defining functions in Dart code.

The benefit of defining custom elements in Jael as opposed to in a client-side framework is that they build directly to standard HTML, and require no additional features in an end-user's browser.

## Defining Elements

To define your own element, simply use the `<element>` tag:

```html
<element name="todo-item">
    <input type="checkbox" checked=todo.completed disabled>
    {{ todo.text }}
</element>
```

The best practice is to define elements in their own file, so that they can be imported into the scope using an [include](/templates-and-views/jael3/directive-include) tag:

```html
<extend src="layout.jl">
    <block name="content">
        <include src="todo-item.jl" />
        <todo-item for-each=todos @todo=item />
    </block>
</extend>
```

## Passing Data

You might have noticed that in the earlier example, some attributes of the `todo-item` were prefixed with an arroba (`@`), while others were not. There is, of course, a reason for this.

When rendering a custom element, attributes with the `@` are injected into the custom element's scope. This is analogous to passing arguments to a function.

Attributes without the `@` are passed to the root of the created element. Thus, you can pass attributes like `class` and `style` to custom elements, and therefore apply visual effects, etc.

Directives like `if` and `for-each` also work with custom elements, of course.

## Specifying a Tag Name

By default, custom elements are replaced with a `div`. There may be times you wish to override this, for example, to render a `todo-item` as an `a` element.

Use the special `as` attribute to facilitate this:

```html
<todo-item as="a" for-each=todos @todo=item />
```

## Emitting without a Tag Name

There may be times when you need to emit the contents of an element, *without* a container element. In such a case, pass `as=false`, and the contents will be rendered in the current context, rather than in a new element.


# Strict Resolution

Dart is an imperative language, where you have the agency to cast values to other types, to execute multiple statements, and ultimately create a program by explicitly declaring every action that should be taken.

HTML, and subseqently, Jael, are declarative markup languages, and thus give you considerably less control over the flow of data and type information. Functionality like type checks, which are manageable in Dart, are both unintuitive and verbose in a markup language.

To compensate, Jael can enable or disable what can be referred to as *strict resolution*. `package:angel3_jael` by default disables strict resolution, and `strictResolution` is available as a parameter to both the `jael` function in Angel3, and the `Render()` constructor in Jael.

Jael's expression parser is **not** the one from `package:analyzer`, so the evaluation of expressions at runtime is up to the `Renderer` class. When strict resolution is on, all referenced identifiers **must** be present in the scope, and the only values allowed for `if`, conditionals, and similar expressions are `bool`.

For example, take the following snippet:

```html
<ul if=user?.name?.isNotEmpty>
  <li>
    Talk to @{{ user.name }}
  </li>
</ul>
```

If strict resolution is **on**:

* If `user` is not in the scope of values passed to the renderer, an error will be thrown.
* If the expression `user?.name?.isNotEmpty` is `null`, then an error will be thrown.

If strict resolution is **off**:

* If `user` is not in the scope of values, Jael will just substitute it with `null`.
* If `user?.name` is `null`, Jael will substitute the expression with `null`.
* If the expression `user?.name?.isNotEmpty` does not evaluate to `true` (that is to say, it *can* be `null`!), then the `ul` will simply not be rendered.

Overall, strict resolution should likely be off for most cases, as type checking is not often that important when writing HTML templates.


# Directive: declare

Use a `declare` tag to *create* named variables within a block scope. This is analogous to a variable declaration in Dart.

This Dart code:

```dart
var one = 1, two = 2, three = null;
```

Becomes this Jael:

```html
<declare one=1 two=2 three>
 // Scoped content...
</declare>
```

Another example (this is actually the test for `declare` functionality):

```html
<div>
 <declare one=1 two=2 three=3>
   <ul>
    <li>{{one}}</li>
    <li>{{two}}</li>
    <li>{{three}}</li>
   </ul>
   <ul>
    <declare three=4>
      <li>{{one}}</li>
      <li>{{two}}</li>
      <li>{{three}}</li>
    </declare>
   </ul>
 </declare>
</div>
```

Which yields:

```html
<div>
  <ul>
    <li>
      1
    </li>
    <li>
      2
    </li>
    <li>
      3
    </li>
  </ul>
  <ul>
    <li>
      1
    </li>
    <li>
      2
    </li>
    <li>
      4
    </li>
  </ul>
</div>
```


# Directive: for-each

To render content for each member of an `Iterable`, use the `for-each` directive:

```html
<ul>
  <li for-each=artists as="artist">
    <a href="/artist/" + artist.id>
      {{ artist.name }}
    </a>
  </li>
</ul>
```

Use an `as` attribute to specify the name each member of the iterable will be scoped as. If it is not provided, it defaults to `item`:

```html
<ul>
  <li for-each=[1, 2, 3]>
    {{ item }} takes {{ item.bitLength }} bit(s) to store.
  </li>
</ul>
```


# Directive: extend

Jael supports template inheritance by means of `extend` and `block`.

Note the following example:

```html
<!-- layout.jl -->
<html>
    <head>
        <title>{{ title }} - My App</title>
    </head>
    <body>
        <block name="content"></block>
        <div class="footer">
          <!-- Footer content... -->
        </div>
    </body>
</html>

<!-- hello.jl -->
<extend src="layout.jl">
  <block name="content">
    <img src=user.avatar ?? "http://example.com/img/default-avatar">
    Hello, {{ user.name }}!
  </block>
</extend>
```

To extend a layout, instead of the file containing an `<html>` node, create a file with an `<extend>` node. The `src` attribute should point to the correct file. Then, add `<block>` tags that will replace the corresponding `<block>` tags declared in the parent file.


# Directive: if

Similar to `*ngIf` in Angular, Jael supports a simple `if` directive. Use `if` to only an element if a certain condition is `true`:

```html
<i if=user.locale == 'en'>
  Hello, {{ user.name }}!
</i>
<i if=user.locale == 'jp'>
  こんにちは, {{ user.name }}!
</i>
```


# Directive: include

Use an `include` tag to copy in the contents of another template into the current one. The path, specified with a `src` attribute, will be resolved relative to the path of the current file.

This set-up:

```html
<!-- components/todo.jl -->
<div class="list-item">
  <div class="title">{{ todo.title }}</div>
</div>

<!-- todo_list.jl -->
<div class="list">
  <div for-each=todos as="todo">
    <include src="components/todo.jl" />
  </div>
</div>
```

Will be renderered as:

```html
<div class="list">
  <div>
    <div class="list-item">
      <div class="title">Clean your room</div>
    </div>
  </div>
  <div>
    <div class="list-item">
      <div class="title">Do the dishes</div>
    </div>
  </div>
</div>
```


# Directive: switch

Jael's `switch` directive is similar to a Dart `switch` statement. It takes a `value` as input, and evaluates an infinite number of `case` tags, only evaluating the first whose value matches the one in question. A `default` tag can be provided as a fallback.

```html
<switch value=account.isDisabled>
  <case value=true>
    Good riddance!
  </case>
  <case value=false>
    You are in good standing.
  </case>
  <default>
    Weird...
  </default>
</switch>
```


# Authentication


# About

`angel3_auth` is, in many ways, a port of Passport to the Angel3 Framework.

## Usage

```dart
// Of course, create an instance.
//
// A `jwtKey` is not required, but without a pre-established secret,
// JWT's will automatically be invalidated whenever the server restarts.
//
// If your `allowCookie` is `true` (`true` by default), then JWT's can also be carried within
// a `token` cookie. This can be annoying during the development stage, as it is difficult to remove
// cookies from Dartium.
//
// By convention, try to avoid cookies and session use whenever possible.
var auth = AngelAuth(jwtKey: 'MY_SECRET', allowCookie: false);

// The following two functions de/serialize a user from a JWT.
auth.serializer = (user) async => serializeUserToId();
auth.deserializer = (id) async => deserializeUserFromId();

// Strategies are used to implement authentication methods
auth.strategies.add['local'] = LocalAuthStrategy((username, password) async {
  return await findCorrespondingUser(username, password);
});

// Use `authenticate` to log users in
var app = Angel()..post('/auth/local', auth.authenticate('local'));

// Finally, call our instance as a plugin.
//
// This will a global middleware to decode JWT's and deserialize them,
// and also creates a route to refresh JWT's.
await app.configure(auth);
```


# Strategies

Just like in Passport, strategies implement authentication via a specific provider. To create your own strategy, you need to implement the `AuthStrategy` class.

All strategies must implement `authenticate(req, res, [opts])`.

## authenticate

This method should only have three possible results.

**Possibility #1:** Return `true`

This signifies that whatever authentication process you performed was completed successfully, and that it did not produce any result that needs to be serialized.

**Possibility #2:** Return `false`

This represents an authentication failure, and will throw a `401 Not Authenticated` error.

**Possibility #3:** Return something else entirely

This signifies that although the user was successfully authenticated, the authenticated user needs to be serialized into another format for the entire authentication flow to be considered complete.

For example, you usually need to save a user's ID after authentication.

```dart
import 'package:angel3_auth/angel3_auth.dart';

class MyStrategy implements AuthStrategy {
  @override
  authenticate(req, res, [opts]) async {
    final user =
      await login(req.body['username'], req.body['password']);

    return user != null ? user : false;
  }
}
```


# Local

See the [docs](https://pub.dev/documentation/angel3_auth/latest/angel3_auth/LocalAuthStrategy-class.html).


# Databases


# Object Relational Mapping (ORM)


# About

Angel3, like many other Web server frameworks, features support for object-relational mapping, or *ORM*. ORM tools allow for conversion from database results to Dart classes.

Angel3's ORM uses Dart's `build` system to generate query builder classes from your `Model` classes, and takes advantage of Dart's strong typing to prevent errors at runtime.

Take, for example, the following class:

```dart
@orm
abstract class _Pokemon extends Model {
    String get nickName;

    int get level;

    int get experiencePoints;

    @belongsTo
    PokemonTrainer get trainer;

    @belongsTo
    PokemonSpecies get species;

    @belongsTo
    PokemonAttack get attack0;

    @belongsTo
    PokemonAttack get attack2;

    @belongsTo
    PokemonAttack get attack3;

    @belongsTo
    PokemonAttack get attack4;
}
```

`package:angel3_orm_generator` will generate code that lets you do the following:

```dart
app.get('/trainer/int:id/first_moves', (req, res) async {
    var id = req.params['id'] as int;
    var executor = req.container.make<QueryExecutor>();
    var trainer = await findTrainer(id);
    var query = PokemonQuery()..where.trainerId.equals(id);
    var pokemon = await query.get(executor);
    return pokemon.map((p) => p.attack0.name).toList();
});
```

This section of the Angel3 documentation consists mostly of guides, rather than technical documentation.

For more in-depth documentation, see the actual `angel3_orm` project on Github:

<https://github.com/dukefirehawk/angel/tree/master/packages/orm>


# Basic Functionality

Before starting with the ORM, it is highly recommended to familiar one's self with `package:angel3_serialize`, as it is the foundation for `package:angel3_orm`:

<https://github.com/dukefirehawk/angel/tree/master/packages/serialize>

To enable the ORM for a given model, simply add the `@orm` annotation to its definition:

```dart
@orm
@serializable
abstract class _Todo {
    bool get isComplete;

    String get text;

    @Column(type: ColumnType.long)
    int get score;
}
```

The generator will produce a `TodoQuery` class, which contains fields corresponding to each field declared in `_Todo`. Each of `TodoQuery`'s fields is a subclass of `SqlExpressionBuilder`, corresponding to the given type. For example, `TodoQuery` would look *something* like:

```dart
class TodoQuery extends Query<Todo, TodoQueryWhere> {
    BooleanSqlExpressionBuilder get isComplete;

    StringSqlExpressionBuilder get text;

    NumericSqlExpressionBuilder<int> get score;
}
```

Thus, you can query the database using plain-old-Dart-objects (*PODO's*):

```dart
Future<List<Todo>> leftToDo(QueryExecutor executor) async {
    var query = TodoQuery()..where.isComplete.isFalse;
    return await query.get(executor);
}

Future<void> markAsComplete(Todo todo, QueryExecutor executor) async {
    var query = TodoQuery()
        ..where.id.equals(todo.idAsInt)
        ..values.isComplete = true;

    await query.updateOne(executor);
}
```

The glue holding everything together is the `QueryExecutor` interface. To support the ORM for any arbitrary database, simply extend the class and implement its abstract methods.

Consumers of a `QueryExecutor` typically inject it into the app's [dependency injection](https://github.com/dukefirehawk/angel3-guide/blob/master/dependency-injection.md) container:

```dart
app.container.registerSingleton<QueryExecutor>(PostgresExecutor(...));
```

*At the time of this writing*, there is only support for PostgreSQL, though more databases may be added eventually.


# Relations

Relational modeling is one of the most commonly-used features of sql databases - after all, it *is* the namesake of the term "relational database."

Angel supports the following kinds of relations by means of annotations on fields:

* `@hasOne` (one-to-one)
* `@hasMany` (one-to-many)
* `@belongsTo` (one-to-one)
* `@manyToMany` (many-to-many)

By default, the keys for columns are inferred automatically. In the following case:

```dart
@orm
@serializable
abstract class _Wheel extends Model {
  @belongsTo
  Car get car;
}
```

The local key defaults to `car_id`, and the foreign key defaults to `id`. You can manually override these:

```dart
@BelongsTo(localKey: 'carId', foreignKey: 'licenseNumber')
Car get car;
```

The ORM computes relationships by performing `JOIN`s, so that even complex relationships can be fetched using just one query, rather than multiple.

## Many-to-many Relationships

A very common situation that occurs when using relational databases is where two tables may be bound to multiple copies of each other. For example, in a school database, each student could be registered to multiple classes, and each class could have multiple students taking it.

This is typically handled by creating a third table, which joins the two together. In the Angel ORM, this is relatively straightforward:

```dart
@orm
@serializable
abstract class _Class extends Model {
  String get courseName;

  @ManyToMany(_Enrollment)
  List<_Student> get students;
}

@orm
@serializable
abstract class _Student extends Model  {
  String get name;
  int get year;

  @ManyToMany(_Enrollment)
  List<_Class> get classes;
}

@orm
@serializable
abstract class _Enrollment {
    @belongsTo
    _Student get student;

    @belongsTo
    _Class get class_;
}
```


# Migrations

Angel3 ORM ships with support for running database migrations, using a system modeled over [that of Laravel](https://laravel.com/docs/5.7/migrations).

An example is shown below:

```dart
class UserMigration implements Migration {
  @override
  void up(Schema schema) {
    schema.create('users', (table) {
      table
        ..serial('id').primaryKey()
        ..varChar('username', length: 32).unique()
        ..varChar('password')
        ..boolean('account_confirmed').defaultsTo(false);
    });
  }

  @override
  void down(Schema schema) {
    schema.drop('users');
  }
}
```

Migrations can be used to either create, alter, or drop database tables.

For more in-depth documentation, consult the `angel3_migration` documentation:

<https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_migration>

If you use `angel3_orm_generator`, then a migration will be generated by default for each class annotated with `@orm`.

To disable this:

```dart
@Orm(generateMigrations: false)
abstract class _MyModel extends Model {}
```

## Running Migrations

Using `package:angel3_migration_runner`, we can create executables that run our database migrations:

```dart
import 'package:angel3_migration_runner/angel3_migration_runner.dart';
import 'package:angel3_migration_runner/postgres.dart';
import 'package:postgres/postgres.dart';
import '../../angel3_migration/example/todo.dart';

var migrationRunner = PostgresMigrationRunner(
  PostgreSQLConnection('127.0.0.1', 5432, 'test'),
  migrations: [
    UserMigration(),
    TodoMigration(),
  ],
);
```

Running this file will produce output like the following:

```bash
Executes Angel3 migrations.

Usage: migration_runner <command> [arguments]

Global options:
-h, --help    Print this usage information.

Available commands:
  help       Display help information for migration_runner.
  refresh    Resets the database, and then re-runs all migrations.
  reset      Resets the database.
  rollback   Undoes the last batch of migrations.
  up         Runs outstanding migrations.

Run "migration_runner help <command>" for more information about a command.
```

The migration runner keeps track of a `migrations` table, in order to be able to keep track of which migrations it has run.


# PostgreSQL

PostgreSQL support is provided by way of `package:angel3_orm_postgres`. The `PostgreSQLExecutor` implements `QueryExecutor`, and takes care of running prepared queries, and passing values to the database server.

`angel3 init` projects using the ORM include helpers like this to load app configuration into a database connection:

```dart
Future<void> configureServer(Angel app) async {
  var connection = await connectToPostgres(app.configuration);
  await connection.open();

  app
    ..container.registerSingleton<QueryExecutor>(PostgreSQLExecutor(connection))
    ..shutdownHooks.add((_) => connection.close());
}

Future<PostgreSQLConnection> connectToPostgres(Map configuration) async {
  var postgresConfig = configuration['postgres'] as Map ?? {};
  var connection = PostgreSQLConnection(
      postgresConfig['host'] as String ?? 'localhost',
      postgresConfig['port'] as int ?? 5432,
      postgresConfig['database_name'] as String ??
          Platform.environment['USER'] ??
          Platform.environment['USERNAME'],
      username: postgresConfig['username'] as String,
      password: postgresConfig['password'] as String,
      timeZone: postgresConfig['time_zone'] as String ?? 'UTC',
      timeoutInSeconds: postgresConfig['timeout_in_seconds'] as int ?? 30,
      useSSL: postgresConfig['use_ssl'] as bool ?? false);
  return connection;
```

Typically, you'll want to use app configuration to create the connection, rather than hard coding values.


# NoSQL

As one can imagine, a SQL ORM cannot be used with a NoSQL database. However, this is usually not a problem, because the ideal use cases for NoSQL databases typically do not require the functionality present in an ORM (namely, relation support).

With a NoSQL databases, you can use the `Service` API (you likely already are!), and use `Service.map` to deal with Dart data only, rather than messing around with `Map`s, and risking typos and refactoring challenges.

If you are using `package:angel3_serialize`, this is pretty easy:

```dart
abstract class _Greeting extends Model {
    String get text;

    double get attachedMoney;
}

var service = MongoService(...);
var mappedService = service.map(GreetingSerializer.fromMap, GreetingSerializer.toMap);

// Now you can get Greeting instances.
var greeting = await mappedService.read(id);
print([greeting.text, greeting.attachedMoney]);
```


# Extensions and Plugins


# Using Plug-ins

* [Using Plug-ins](#using-plug-ins)
  * [Execution Order](#execution-order)
  * [Writing a Plug-in](/extensions-and-plugins/writing-a-plugin)
* [Next Up...](#next-up)

## Using Plug-ins

Angel3 is designed to be extensible. As such, it exposes a typedef, `AngelConfigurer`, that has special privileges within the framework - they act as plug-ins and can be called via `app.configure()`.

Plug-ins simply need to accept an `Angel` instance as a parameter, and return a `Future` (the result of which will be ignored, unless it throws an error). `Angel` instances have several facilities available to be customized, and thus it is easy to use a custom plug-in to bring about desired functionality within your application.

```dart
typedef Future AngelConfigurer(Angel app);
```

As a convention, Angel3 plug-ins should be hooked up **before** the call to `startServer`.

```dart
import 'dart:io';
import 'package:angel3_framework/angel3_framework';

plugin(Angel app) async {
  print("Do stuff here");
}

void main() async {
  Angel app = Angel();
  await app.configure(plugin);
  await app.startServer();
}
```

### Execution Order

Plugins are usually immediately invoked by `app.configure()`. However, you may run into certain plug-ins that depend on other facilities already being available, or all of your [services](/under-the-hood/service-basics) already being mounted. You can set aside a plug-in to be run just before server startupby adding it to `app.startupHooks`, instead of directly calling `app.configure()`.

```dart
app.startupHooks.addAll([
  myPlugin(),
  AngelWebSocket().configureServer,
  fooBarBazQuux()
]);
```

Likewise, you can add hooks that run just before the app is shutdown, via `Angel.shutdownHooks`.

## Next Up

Learn how to generate content for clients by [rendering views](broken://pages/-MbULaLA6pAZM6LPfECx).


# Writing a Plugin

[Guidelines](#guidelines)

Writing a [plug-in](/extensions-and-plugins/using-plug-ins) is easy. You can provide plug-ins as either functions, or classes:

```dart
AngelConfigurer awesomeify({String message = 'This request was intercepted by an awesome plug-in.'}) {
  return (Angel app) async {
    app.fallback((req, res) async => res.write(message));
  };
}

class MyAwesomePlugin {
  @override
  Future<void> configureServer(Angel app) async {
    app.responseFinalizers.add((req, res) async {
      res.headers['x-be-awesome'] = 'All the time :)';
    });
  }
}

await app.configure(MyAwesomePlugin().configureServer);
```

## Guidelines

* Plugins should only do one thing, or serve one purpose.
* Functions are preferred to classes.
* Always need to be well-documented and thoroughly tested.
* Make sure no other plugin already serves the purpose.
* Use the provided Angel3 API's whenever possible. This will help your plugin resist breaking change in the future.
* Plugins should *generally* be small, as they usually serve just one purpose.
* Plugins are allowed to modify app configuration.
* Stay away from `req.rawRequest` and `res.rawResponse` if possible. This can restrict people from using your plugin on multiple platforms.
* Avoid checking `app.isProduction`; leave that to user instead.
* Always use `req.parseBody()` before accessing the request body.

Finally, your plugin should expose common options in a simple way. For example, the (deprecated) [compress](https://github.com/angel-dart/compress) plugin has a shortcut function, `gzip`, to set up GZIP compression, whereas for any other codec, you would manually have to specify additional options.

This can greatly aid readability, as there is simply less text to read in the most common cases.

```dart
void main() {
  var app = Angel();

  // Calling gzip()
  app.responseFinalizers.add(gzip());

  // Easier than:
  app.responseFinalizers.add(compress('lzma', lzma));
}
```


# Under the hood


# Basic Routing

* [Routing](#routing)
* [Route Parameters](#route-parameters)
  * [Parsing Parameters](#parsing-parameters)
* [`RegExp` Routes](#regexp-routes)
* [Mounting and Sub-Apps](#sub-apps)
* [Route Groups](#route-groups)
* [Extended Documentation](#extended-documentation)
* [Next Up...](#next-up)

## Routing

There is only one method responsible for adding routes to your application:

```dart
app.addRoute('<method>', '<path>', requestHandler);
```

However, the following methods are available for convenience, and are the ones you will use most often. Each method's name responds to an HTTP request method. For example, a route declared with `app.get(...)`, will respond to HTTP `GET` requests.

```dart
app.get('<path>', requestHandler);
app.post('<path>', requestHandler);
app.patch('<path>', requestHandler);
app.delete('<path>', requestHandler);
```

Your `requestHandler` should take the following form:

```dart
typedef FutureOr<dynamic> RequestHandler(RequestContext req, ResponseContext res);
```

Your `requestHandler` can return any Dart value, whether a function, or an object. See the [Requests and Responses](/under-the-hood/requests-and-responses#return-values) pages for detailed documentation.

Route paths *do not* have to begin with a forward slash, as leading and trailing slashes are stripped from route paths internally.

## Route Parameters

Say you're building an API, or an MVC application. You typically want to serve the same view template on multiple paths, corresponding to different ID's. You can do this as follows, and all parameters will be available via `req.params`:

```dart
app.get('/todos/:id', (req, res) async => {'id': req.params['id']});
```

Remember, route parameters *must* be preceded by a colon (':'). Parameter names must start with a letter or underscore, optionally followed by letters, underscores, or numbers. Parameters will match any character except a forward slash ('/') in a request URI.

Examples:

* `:id`
* `:_hello`
* `:param123`
* `info_about_:username`

### Parsing Parameters

With a special syntax, you can build routes that automatically parse parameters as `ints` or `doubles`:

```dart
app
  ..get('/add/int:number', (req, res) => req.params['number'] * 3)
  ..get('/multiply/double:number', (req, res) => req.params['number'] * 5.0);
```

## RegExp Routes

Route parameters can also have custom regular expressions, to remove the requirement of manual parsing. Simply enclose the regular expression in a set of parentheses following the parameter's name.

```dart
app.get(r'/number/:num([0-9]+(\.[0-9])?)', ...);
```

## Sub-Apps

You can `mount` routers, or `use` entire sub-apps.

```dart
var app = Angel();
app.get('/', 'Hello!');

var subRouter = Router()..get('/', 'Subroute');
app.mount('/sub', subApp);
// Now, you can visit /sub and receive the message "Subroute"

var subApp = Angel()..get('/hello', 'world');
app.use('/api', subApp);

// GET /api/hello returns "world"
```

## Route Groups

Routes can also be grouped together. Route parameters will be applied to sub-routes automatically. Route groups can be nested as well.

```dart
app.group('/user/:id', (router) {
  router
    ..get('/messages', (String id) => fetchUserMessages(id))
    ..group('/nested', ...);
});
```

## Extended Documentation

For more documentation on the router, see [Angel3 Route Repository](https://github.com/dukefirehawk/angel/tree/master/packages/route). [`angel3_route`](https://pub.dartlang.org/packages/angel3_route) has no `dart:io` or `dart:mirrors` dependency, and it also supports browser use (both hash and push state).

## Next Up

Learn how [Requests and Responses](/under-the-hood/requests-and-responses) let you reuse functionality across your entire routing setup.


# Requests & Responses

* [Requests and Responses](#requests-and-responses)
  * [Return Values](#return-values)
  * [Other Parameters](#other-parameters)
  * [Queries, Files and Bodies](#queries-files-and-bodies)
* [Next Up...](#next-up)

## Requests and Responses

Angel3 is inspired by Express, and such, request handlers in general resemble those from Express. Request handlers can return any Dart object (see [how they are handled](#return-values)). Basic request handlers accept two parameters:

* [`RequestContext`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/RequestContext-class.html) - Contains vital information about the client requesting a resource, such as request method, request body, IP address, etc. The request object can also be used to pass information from one handler to the next.
* [`ResponseContext`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/ResponseContext-class.html) - Allows you to send headers, write data, and more, to be sent to the client. To prevent a response from being modified by future handlers, call `res.end()` to prevent further writing.

### Return Values

Request handlers can return any Dart value. Return values are handled as follows:

* If you return a `bool`: Request handling will end prematurely if you return `false`, but it will continue if you return `true`.
* If you return `null`: Request handling will continue, unless you closed the response object by calling [`res.close()`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/ResponseContext/close.html). Some response methods, such as [`res.redirect()`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/ResponseContext/redirect.html) or [`res.serialize()`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/ResponseContext/serialize.html) automatically close the response.
* A `RequestHandler`: the returned handler will be executed.
* A `Stream`: `toList` will be called, and then returned.
* A `Future`: it will be awaited, and then returned.
* Anything else: Whatever other Dart value you return will be serialized as a response. The default method is to encode responses as JSON, using `json.encode`. However, you can change a response's serialization method by setting `res.serializer = foo;`. If you want to assign the same serializer to all responses, globally set [`serializer`](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/Angel/serializer.html) on your Angel instance. If you are only returning JSON-compatible Dart objects, like Maps or Lists, you might consider injecting `JSON.encode` as a serializer, to improve runtime performance (this is the default in `2.0`).

### Other Parameters

Request handlers can take other parameters, instead of just a `RequestContext` and `ResponseContext`. Consult the [dependency injection documentation](/under-the-hood/dependency-injection#in-routes-and-controllers).

### Queries, Files and Bodies

You can access a mutable `Map` based on the URI query parameters by calling `RequestContext.queryParameters`.

Consult the [body parsing documentation](/under-the-hood/body-parsing) to understand how to handle user input.

If you [write your own plugin](/extensions-and-plugins/writing-a-plugin), be sure to use the `lazy` alternatives.

For more information, see the API docs:

[RequestContext](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/RequestContext-class.html)

[ResponseContext](https://pub.dev/documentation/angel3_framework/latest/angel3_framework/ResponseContext-class.html)

## Next Up

Now, let's learn about Angel3's [Request Lifecycle](https://github.com/dukefirehawk/angel3-guide/blob/master/guides/request-lifecyle.md).


# Request Lifecycle

Requests in the Angel3 framework go through a relatively complex lifecycle, and to truly master the framework, one must understand that lifecycle.

1. `startServer` is called.
2. Each `HttpRequest` is sent through `handleRequest`.
3. `handleRequest` converts the `HttpRequest` to a `RequestContext`, and converts its `HttpResponse` into a `ResponseContext`.
4. `angel3_route` is used to match the request path to a list of request handlers.
5. Each handler is executed.
6. If the response is using streaming, and not buffering content, skip to step 8 (default).
7. All `responseFinalizers` are run.
8. If `res.isDetached == false`, all headers, the status code and the response buffer are sent through the actual `HttpResponse`.
9. The `HttpResponse` is closed.

If at any point an error occurs, Angel3 will catch it. See the [error handling](/under-the-hood/error-handling) docs for more.

## Next Up

Continue reading to learn about [Dependency Injection](/under-the-hood/dependency-injection).


# Dependency Injection

Angel3 uses a [container hierarchy](https://github.com/dukefirehawk/angel/tree/master/packages/container) for DI. Dependency injection makes it easier to build applications with multiple moving parts, because logic can be contained in one location and reused at another place in your application.

## Adding a Singleton

```dart
Future<void> myPlugin(Angel app) async  {
  app.container.registerSingleton(SomeClass("foo"));
  app.container.registerSingleton<SomeAbstractClass>(MyImplClass());
  app.container.registerFactory((_) => SomeClass("foo"));
  app.container.registerLazySingleton((_) => SomeOtherClass());
  app.container.registerNamedSingleton('yes', Yes());
}
```

You can also inject within a `RequestContext`, as each one has a `controller` property that extends from the app's global container.

Accessing these injected properties is easy, and strongly typed:

```dart
// Inject types.
var todo = req.container.make<Todo>();
print(todo.isComplete);

// Or by name
var db = await req.container.findByName<Db>('database');
var collection = db.collection('pets');
```

## In Routes and Controllers

In Angel3, by wrapping a function in a call to `ioc`, you can automatically inject the dependencies of any route handler.

```dart
app.get("/some/class/text", ioc((SomeClass singleton) => singleton.text)); // Always "foo"

app.post("/foo", ioc((SomeClass singleton, {Foo optionalInjection}));

@Expose("/my/controller")
class MyController extends Controller {

  @Expose("/bar")
  // Inject classes from container, request parameters or the request/response context :)
  bar(SomeClass singleton, RequestContext req) => "${singleton.text} bar"; // Always "foo bar"

  @Expose("/baz")
  baz({Foo optionalInjection});
}
```

As you can imagine, this is very useful for managing things such as database connections.

```dart
configureServer(Angel app) async {
  var db = Db("mongodb://localhost:27017/db");
  await db.open();
  app.container.registerSingleton(db);
}

@Expose("/users")
class ApiController extends Controller {
  @Expose("/:id")
  fetchUser(String id, Db db) => db.collection("users").findOne(where.id(ObjectId.fromHexString(id)));
}
```

## Dependency-Injected Controllers

`Controller`s have dependencies injected without any additional configuration by you. However, you might want to inject dependencies into the constructor of your controller.

```dart
@Expose('/controller')
class MyController {
  final AngelAuth auth;
  final Db db;

  MyController(this.auth, this.db);

  @Expose('/login')
  login() => auth.authenticate('local');
}

void main() async {
  // At some point in your application, register necessary dependencies as singletons...
  app.container.registerSingleton(auth);
  app.container.registerSingleton(db);

  // Create the controller with injected dependencies
  await app.mountController<MyController>();
}
```

## Enabling `dart:mirrors` or other Reflection

By default, Angel3 will use the `EmptyReflector()` to power its `Container` instances, which has no support for `dart:mirrors`, so that it can be used in contexts where Dart reflection is not available.

However, by using a different `Reflector`, you can use the full power of Angel3's DI system. `angel3 init` projects use the `MirrorsReflector()` by default.

If your application is using any sort of functionality reliant on annotations or reflection, either include the MirrorsReflector, or use a static reflector variant.

The following use cases require reflection:

* Use of `Controller`s, via `@Expose()` or `@ExposeWS()`
* Use of dependency injection into **constructors**, whether in controllers or plain `container.make` calls
* Use of the `ioc` function in any route

The `MirrorsReflector` from `package:angel3_container/mirrors.dart` is by far the most convenient pattern, so use it if possible.

However, the following alternatives exist:

* Generation via `package:angel3_container_generator`
* Creating an instance of `StaticReflector`
* Manually implementing the `Reflector` interface (cumbersome; not recommended)

## Next Up

Continue reading to learn about [Middleware](/under-the-hood/middleware).


# Middleware

* [Middleware](#middleware)
  * [Denying Requests via Middleware](#denying-requests-via-middleware)
  * [Declaring Middleware](#declaring-middleware)
  * [Named Middleware](#named-middleware)
  * [Global Middleware](#global-middleware)
  * [`chain([...])`](#chain)
  * [\*\*Maintaining Code Readability](#maintaining-code-readability)
* [Next Up...](#next-up)

## Middleware

Sometimes, it becomes to recycle code to run on multiple routes. Angel3 allows for this in the form of *middleware*. Middleware are frequently used as authorization filters, or to serialize database data for use in subsequent routes. Middleware in Angel3 can be any route handler, whether a function or arbitrary data. You can also throw exceptions in middleware.

### Denying Requests via Middleware

A middleware should return either `true` or `false`. If `false` is returned, no further routes will be executed. If `true` is returned, route evaluation will continue. (more on request handler return values [here](/under-the-hood/requests-and-responses#return-values)).

In practice, you will only need to write a `return` statement when you are returning `true`.

As you can imagine, this is perfect for authorization filters.

### Declaring Middleware

You can call a router's `chain` method, or assign middleware in the `middleware` parameter of a route method.

```dart
// All ways ultimately accomplish the same thing.
// Keep it readable!

// Cleanest. Use when it doesn't create visual clutter of its own.
app.chain([cors()]).get('/', 'world!');

// Another readable use of the `.chain()` method.
app.chain([cors()]).get('/something', (req, res) {
  // Do something here...
});

// Use when more than one middleware is involved, or when
// using an anonymous function as a handler (or middleware that spans
// multiple lines)
app.get('/', chain([
  someMiddleware,
  (req, res) => ...,
  (req, res) {
    return 'world!';
  },
]));

// The `middleware: ` parameter is used internally by `package:angel_route`.
// Avoid using it when you can.
app.get('/', 'world!', middleware: [someListOfMiddleware]);
```

Though this might at first seem redundant, there are actually reasons for all three existing.

By convention, though, follow these *readability* rules when building Angel3 servers:

* Routes with no middleware should not use `chain`, `app.chain`, or \`middleware. Self-explanatory.
* Routes with one middleware and one handler should use `app.chain([...])` when:
  * The construction of all the middleware does not take more than one line.
* In all other cases, use the `chain` meta-handler.
* Avoid using `middleware: ...` directly, as it is used internally `package:route`.

### Global Middleware

To add a handler that handles *every* request, call `app.fallback`. This is merely shorthand for calling `app.all('*', <handler>)`. (more info on request lifecycle [here](/under-the-hood/request-lifecycle)).

```dart
app.fallback((req, res) async => res.close());
```

For more complicated middleware, you can also create a class.

Canonically, when using a class as a request handler, it should provide a `handleRequest(RequestContext, ResponseContext)` method. This pattern is seen throughout many Angel3 plugins, such as `VirtualDirectory` or `Proxy`.

The reason for this is that a name like `handleRequest` makes it very clear to anyone reading the code what it is supposed to do. This is the same rationale behind [controllers](/under-the-hood/controllers) providing a `configureServer` method.

```dart
class MyCanonicalHandler {
 Future<bool> handleRequest(RequestContext req, ResponseContext res) async {
  // Do something cool...
 }
}

app.use(MyCanonicalHandler().handleRequest);
```

### Maintaining Code Readability

Take the following example. At first glance, it might not be very easy to read.

```dart
app.get('/the-route', chain([
  banIp('127.0.0.1'),
  'auth',
  ensureUserHasAccess(),
  (req, res) async => true,
  takeOutTheTrash()
  (req, res) {
   // Your route handler here...
  }
]));
```

In general, consider it a code smell to stack multiple handlers onto a route like this; it hampers readability, and in general just doesn't look good.

Instead, when you have multiple handlers, you can split them into multiple `chain` calls, assigned to variables, which have the added benefit of communicating what each set of middleware does:

```dart
var authorizationMiddleware = chain([
 banIp('127.0.0.1'),
 requireAuthentication(),
 ensureUserHasAccess(),
]);

var someOtherMiddleware = chain([
 (req, res) async => true,
 takeOutTheTrash(),
]);

var theActualRouteHandler = (req, res) async {
 // Handle the request...
};

app.get('/the-route', chain([
 authorizationMiddleware,
 someOtherMiddleware,
 theActualRouteHandler,
]);
```

**Tip**: Prefer using named functions as handlers, rather than anonymous functions, or concrete objects.

## Next Up

Take a good look at [controllers](/under-the-hood/controllers) in Angel3!


# Controllers

* [Controllers](#controllers)
  * [`@Expose()`](#expose)
  * [Allowing Null Values](#allowing-null-values)
  * [Named Controllers and Actions](#named-controllers-and-actions)
  * [Interacting with Requests and Responses](#interacting-with-requests-and-responses)
  * [Transforming Data](#transforming-data)
* [Next Up...](#next-up)

## Controllers

Angel3 has built-in support for controllers. This is yet another way to define routes in a manageable group, and can be leveraged to structure your application in the [MVC](https://en.wikipedia.org/wiki/Model–view–controller) format. You can also use the [`group()`](/under-the-hood/basic-routing#route-groups) method of any [`Router`](https://pub.dev/documentation/angel3_route/latest/angel3_route/Router-class.html).

The metadata on controller classes is processed via reflection *only once*, at startup. Do not believe that your controllers will be crippled by reflection during request handling, because that possibility is eliminated by [pre-injecting dependencies](/under-the-hood/dependency-injection).

```dart
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_container/mirrors.dart';

@Expose("/todos")
class TodoController extends Controller {

  @Expose("/:id")
  getTodo(id) async {
    return await someAsyncAction();
  }

  // You can return a response handler, and have it run as well. :)
  @Expose("/login")
  login() => auth.authenticate('google');
}

main() async {
  Angel app = Angel(reflector: MirrorsReflector());
  await app.configure(TodoController().configureServer);
}
```

Rather than extending from `Routable`, controllers act as [plugins](https://github.com/dukefirehawk/angel3-guide/blob/master/guides/using-plugins.md) when called. This pseudo-plugin will wire all your routes for you.

### @Expose()

The glue that holds it all together is the `Expose` annotation:

```dart
class Expose {
  final String method;
  final Pattern path;
  final List middleware;
  final String as;
  final List<String> allowNull;

  const Expose(Pattern this.path,
      {String this.method: "GET",
      List this.middleware: const [],
      String this.as: null,
      List<String> this.allowNull: const[]});
}
```

### Allowing Null Values

Most fields are self-explanatory, save for `as` and `allowNull`. See, request parameters are mapped to function parameters on each handler. If a parameter is `null`, an error will be thrown. To prevent this, you can pass its name to `allowNull`.

```dart
@Expose("/foo/:id?", allowNull: const["id"])
```

### Named Controllers and Actions

The other is `as`. This allows you to specify a custom name for a controller class or action. `ResponseContext` contains a method, `redirectToAction` that can redirect to a controller action.

```dart
@Expose("/foo")
class FooController extends Controller {
  @Expose("/some/strange/url/:id", as: "bar")
  someActionWithALongNameThatWeWouldLikeToShorten(int id) async {
  }
}

main() async {
  Angel app = Angel();

  app.get("/some/path", (req, res) async => res.redirectToAction("FooController@bar", {"id": 1337}));
}
```

If you do not specify an `as`, then controllers and actions will be available by their names in code. Reflection is cool, huh?

### Interacting with Requests and Responses

Controllers can also interact with [requests and responses](/under-the-hood/requests-and-responses). All you have to do is declare a `RequestContext` or `ResponseContext` as a parameter, and it will be passed to the function.

```dart
@Expose("/hello")
class HelloController extends Controller {
  @Expose("/")
  Future getIndex(ResponseContext res) async {
    await res.render("hello");
  }
}
```

### Transforming Data

You can use [middleware](/under-the-hood/middleware) to de/serialize data to be processed in a controller method.

```dart
Future<bool> deserializeUser(RequestContext req, res) async {
  var id = req.params['id'] as String;
  req.params['user'] = await asyncFetchUser(id);

  return true;
}

@Expose("/user", middleware: const [deserializeUser])
class UserController extends Controller {

  @Expose("/:id/name")
  Future<String> getUserName(User user) async {
    return user.username;
  }

}

main() async {
  Angel app = Angel();
  await app.configure(UserController().configureServer);
}
```

## Next Up

1. How to [handle parse request bodies](/under-the-hood/body-parsing) with Angel3
2. [Using Angel3 Plug-ins](/extensions-and-plugins/using-plug-ins)


# Parsing Request Bodies

Interactive Web applications typically require some type of user input (whether that user is a human, machine, or otherwise is irrelevant). Angel3 features built-in support for parsing request bodies with the following content types:

* `application/x-www-form-urlencoded`
* `application/json`
* `multipart/form-data`

## Body Parsing

All you need to do to parse a request body is call `RequestContext.parseBody`. This method is idempotent, and only ever performs the body-parsing logic once, so it is recommended to call it any time you access the request body, unless you are 100% sure that it has been parsed before.

You can access the body as a `Map`, `List`, or `Object`, depending on your use case:

```dart
app.post('/my_form', (req, res) async {
    // Parse the body, if it has not already been parsed.
    await req.parseBody();

    // Access fields from the body, which is the most common use case.
    var userId = req.bodyAsMap['user_id'] as String;

    // If the user posted a List, i.e., through JSON:
    var count = req.bodyAsList.length;

    // To access the body, regardless of its runtime type:
    var objectBody = req.bodyAsObject as SomeType;
});
```

## Handling File Uploads

In the case of `multipart/form-data`, Angel will also populate the `uploadedFiles` field. The `UploadedFile` wrapper class provides mechanisms for reading content types, metadata, and accessing the contents of an uploaded file as a `Stream<List<int>>`:

```dart
app.post('/upload', (req, res) async {
    await req.parseBody();

    var file = req.uploadedFiles.first;

    if (file.contentType.type == 'video') {
        // Write directly to a file.
        await file.data.pipe(someFile.openWrite());
    }
});
```

## Custom Body Parsing

You can handle other content types by manually parsing the body. You can set `bodyAsObject`, `bodyAsMap`, or `bodyAsList` exactly once:

```dart
Future<void> unzipPlugin(Angel app) async {
    app.fallback((req, res) async {
        if (!req.hasParsedBody
            && req.contentType.mimeType == 'application/zip') {
            var archive = await decodeZip(req.body);
            var fields = <String, dynamic>{};

            for (var file in archive.files) {
                fields[file.path] = file.mode;
            }

            req.bodyAsMap = fields;
        }

        return true;
    });
}
```

If the user did not provide a `content-type` header when `parseBody` is called, a `400 Bad Request` error will be thrown.


# Serialization

![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_serialize?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion) [![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/master/packages/serialize/angel_serialize/LICENSE)

Source-generated serialization for Dart objects. This package uses `package:source_gen` to eliminate the time you spend writing boilerplate serialization code for your models. `package:angel3_serialize` also powers `package:angel3_orm`.

* [Angel3 Serialization](#angel3-serialization)
  * [Usage](#usage)
  * [Models](#models)
  * [Serialization](#serialization)
  * [Customizing Serialization](#customizing-serialization)
  * [Subclasses](#subclasses)
  * [Aliases](#aliases)
  * [Excluding Keys](#excluding-keys)
  * [Required Fields](#required-fields)
  * [Adding Annotations to Generated Classes](#adding-annotations-to-generated-classes)
  * [Custom Serializers](#custom-serializers)
  * [Nesting](#nesting)
  * [ID and Dates](#id-and-dates)
  * [Binary Data](#binary-data)
  * [TypeScript Definitions](#typescript-definitions)
  * [Constructor Parameters](#constructor-parameters)

## Usage

In your `pubspec.yaml`, you need to install the following dependencies:

```yaml
dependencies:
  angel3_model: ^3.0.0
  angel3_serialize: ^4.0.0
dev_dependencies:
  angel3_serialize_generator: ^4.2.0
  build_runner: ^1.0.0
```

With the recent updates to `package:build_runner`, you can build models automatically, anywhere in your project structure, by running `pub run build_runner build`.

To tweak this: [Build Config](https://pub.dartlang.org/packages/build_config)

If you want to watch for file changes and re-build when necessary, replace the `build` call with a call to `watch`. They take the same parameters.

## Models

There are a few changes opposed to normal Model classes. You need to add a `@serializable` annotation to your model class to have it serialized, and a serializable model class's name should also start with a leading underscore.

In addition, you may consider using an `abstract` class to ensure immutability of models.

Rather you writing the public class, `angel3_serialize` does it for you. This means that the main class can have its constructors automatically generated, in addition into serialization functions.

For example, say we have a `Book` model. Create a class named `_Book`:

```dart
import 'package:angel3_model/angel_model.dart';
import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:collection/collection.dart';
part 'book.g.dart';

@serializable
abstract class _Book extends Model {
  String get author;

  @SerializableField(defaultValue: '[Untitled]')
  String get title;

  String get description;

  int get pageCount;

  BookType get type;
}

/// It even supports enums!
enum BookType {
  fiction,
  nonFiction
}
```

The following file will be generated:

* `book.g.dart`

Producing these classes:

* `Book`: Extends or implements `_Book`; may be `const`-enabled.
* `BookSerializer`: static functionality for serializing `Book` models.
* `BookFields`: The names of all fields from the `Book` model, statically-available.
* `BookEncoder`: Allows `BookSerializer` to extend `Codec<Book, Map>`.
* `BookDecoder`: Also allows `BookSerializer` to extend `Codec<Book, Map>`.

And the following other features:

* `bookSerializer`: A top-level, `const` instance of `BookSerializer`.
* `Book.toString`: Prints out all of a `Book` instance's fields.

## Serialization

You can use the generated files as follows:

```dart
myFunction() {
  var warAndPeace = new Book(
    author: 'Leo Tolstoy',
    title: 'War and Peace',
    description: 'You will cry after reading this.',
    pageCount: 1225
  );

  // Easily serialize models into Maps
  var map = BookSerializer.toMap(warAndPeace);

  // Also deserialize from Maps
  var book = BookSerializer.fromMap(map);
  print(book.title); // 'War and Peace'

  // For compatibility with `JSON.encode`, a `toJson` method
  // is included that forwards to `BookSerializer.toMap`:
  expect(book.toJson(), map);

  // Generated classes act as value types, and thus can be compared.
  expect(BookSerializer.fromMap(map), equals(warAndPeace));
}
```

As of `2.0.2`, the generated output also includes information about the serialized names of keys on your model class.

```dart
  myOtherFunction() {
    // Relying on the serialized key of a field? No worries.
      map[BookFields.author] = 'Zora Neale Hurston';
  }
```

## Customizing Serialization

Currently, these serialization methods are supported:

* to `Map`
* to JSON
* to TypeScript definitions

You can customize these by means of `serializers`:

```dart
@Serializable(serializers: const [Serializers.map, Serializers.json])
class _MyClass extends Model {}
```

## Subclasses

`angel3_serialize` pulls in fields from parent classes, as well as implemented interfaces, so it is extremely easy to share attributes among model classes:

```dart
import 'package:angel3_serialize/angel3_serialize.dart';
part 'subclass.g.dart';

@serializable
class _Animal {
  @notNull
  String genus;
  @notNull
  String species;
}

@serializable
class _Bird extends _Animal {
  @DefaultsTo(false)
  bool isSparrow;
}

var saxaulSparrow = Bird(
  genus: 'Passer',
  species: 'ammodendri',
  isSparrow: true,
);
```

## Aliases

Whereas Dart fields conventionally are camelCased, most database columns tend to be snake\_cased. This is not a problem, because we can define an alias for a field.

By default `angel3_serialize` will transform keys into snake case. Use `alias` to provide a custom name, or pass `autoSnakeCaseNames`: `false` to the builder;

```dart
@serializable
abstract class _Spy extends Model {
  /// Will show up as 'agency_id' in serialized JSON.
  ///
  /// When deserializing JSON, instead of searching for an 'agencyId' key,
  /// it will use 'agency_id'.
  ///
  /// Hooray!
  String agencyId;

  @SerializableField(alias: 'foo')
  String someOtherField;
}
```

You can also override `autoSnakeCaseNames` per model:

```dart
@Serializable(autoSnakeCaseNames: false)
abstract class _OtherCasing extends Model {
  String camelCasedField;
}
```

## Excluding Keys

In pratice, there may keys that you want to exclude from JSON. To accomplish this, simply annotate them with `@exclude`:

```dart
@serializable
abstract class _Whisper extends Model {
  /// Will never be serialized to JSON
  @SerializableField(exclude: true)
  String secret;
}
```

There are times, however, when you want to only exclude either serialization or deserialization, but not both. For example, you might want to deserialize passwords from a database without sending them to users as JSON.

In this case, use `canSerialize` or `canDeserialize`:

```dart
@serializable
abstract class _Whisper extends Model {
  /// Will never be serialized to JSON
  ///
  /// ... But it can be deserialized
  @SerializableField(exclude: true, canDeserialize: true)
  String secret;
}
```

## Required Fields

It is easy to mark a field as required:

```dart
@serializable
abstract class _Foo extends Model {
  @SerializableField(isNullable: false)
  int myRequiredInt;

  @SerializableField(isNullable: false, errorMessage: 'Custom message')
  int myOtherRequiredInt;
}
```

The given field will be marked as `@required` in the generated constructor, and serializers will check for its presence, throwing a `FormatException` if it is missing.

## Adding Annotations to Generated Classes

There are times when you need the generated class to have annotations affixed to it:

```dart
@Serializable(
  includeAnnotations: [
    Deprecated('blah blah blah'),
    pragma('something...'),
  ]
)
abstract class _Foo extends Model {}
```

## Custom Serializers

`package:angel3_serialize` does not cover every known Dart data type; you can add support for your own. Provide `serializer` and `deserializer` arguments to `@SerializableField()` as you see fit.

They are typically used together. Note that the argument to `deserializer` will always be `dynamic`, while `serializer` can receive the data type in question.

In such a case, you might want to also provide a `serializesTo` argument. This lets the generator, as well as the ORM, apply the correct (de)serialization rules and validations.

```dart
DateTime _dateFromString(s) => s is String ? HttpDate.parse(s) : null;
String _dateToString(DateTime v) => v == null ? null : HttpDate.format(v);

@serializable
abstract class _HttpRequest {
  @SerializableField(
    serializer: #_dateToString,
    deserializer: #_dateFromString,
    serializesTo: String)
  DateTime date;
}
```

## Nesting

`angel3_serialize` also supports a few types of nesting of `@serializable` classes:

* As a class member, ex. `Book myField`
* As the type argument to a `List`, ex. `List<Book>`
* As the second type argument to a `Map`, ex. `Map<String, Book>`

In other words, the following are all legal, and will be serialized/deserialized. You can use either the underscored name of a child class (ex. `_Book`), or the generated class name (ex `Book`):

```dart
@serializable
abstract class _Author extends Model {
  List<Book> books;
  Book newestBook;
  Map<String, Book> booksByIsbn;
}
```

If your model (`Author`) depends on a model defined in another file (`Book`), then you will need to generate `book.g.dart` before, `author.g.dart`, **in a separate build action**. This way, the analyzer can resolve the `Book` type.

## ID and Dates

This package will automatically generate `id`, `createdAt`, and `updatedAt` fields for you, in the style of an Angel3 `Model`. This will automatically be generated, **only** for classes extending `Model`.

## Binary Data

`package:angel3_serialize` also handles `Uint8List` fields, by means of serialization to and from `base64` encoding.

## TypeScript Definitions

It is quite common to build frontends with JavaScript and/or TypeScript, so why not generate typings as well?

To accomplish this, add `Serializers.typescript` to your `@Serializable()` declaration:

```dart
@Serializable(serializers: const [Serializers.map, Serializers.json, Serializers.typescript])
class _Foo extends Model {}
```

The aforementioned `_Author` class will generate the following in `author.d.ts`:

```typescript
interface Author {
  id: string;
  name: string;
  age: number;
  books: Book[];
  newest_book: Book;
  created_at: any;
  updated_at: any;
}
interface Library {
  id: string;
  collection: BookCollection;
  created_at: any;
  updated_at: any;
}
interface BookCollection {
  [key: string]: Book;
}
```

Fields with an `@Exclude()` that specifies `canSerialize: false` will not be present in the TypeScript definition. The rationale for this is that if a field (i.e. `password`) will never be sent to the client, the client shouldn't even know the field exists.

## Constructor Parameters

Sometimes, you may need to have custom constructor parameters, for example, when using depedency injection frameworks. For these cases, `angel3_serialize` can forward custom constructor parameters.

The following:

```dart
@serializable
abstract class _Bookmark extends _BookmarkBase {
  @SerializableField(exclude: true)
  final Book book;

  int get page;
  String get comment;

  _Bookmark(this.book);
}
```

Generates:

```dart
class Bookmark extends _Bookmark {
  Bookmark(Book book,
      {this.id,
      this.page,
      this.comment,
      this.createdAt,
      this.updatedAt})
      : super(book);

  @override
  final String id;

  // ...
}
```


# Service Basics

* [Services](#services)
  * [Service Parameters and Middleware](#service-parameters-and-middleware)
  * [Mounting Services](#mounting-services)
* [Next Up...](#next-up)

## Services

One of the main concepts within Angel3, which is borrowed from FeathersJS, is a *service*. You more than likely have already dealt with another implementation of the service concept. In Angel3, a *service* is a class that acts as a Web interface and exposes CRUD actions operating on a set of data. Angel3 services extend `Routable`, and thus can be mounted on a certain path and become REST endpoints.

The Angel3 core library includes the `Service` base class, as well as two in-memory service classes. Database adapter packages, such as [`package:angel3_mongo`](https://github.com/dukefirehawk/angel/tree/master/packages/mongo) include service classes that let you interact with a database without writing complex code yourself.

Services can also be filtered or reacted to with [service hooks](https://github.com/dukefirehawk/angel3-guide/blob/master/guides/hooks.md).

A service looks like this:

```dart
class MyService extends Service<String, Map<String, dynamic>> {
  // GET /
  // Fetch all resources. Usually returns a List.
  @override
  Future<List<Map<String, dynamic>>> index([Map<String, dynamic> params]);

  // GET /:id
  // Fetch one resource, by its ID
  @override
  Future<Map<String, dynamic>> read(String id, [Map<String, dynamic> params]);

  // POST /
  // Create a resource. This endpoint should return
  // the created resource.
  @override
  Future<Map<String, dynamic>> create(Map<String, dynamic> data, [Map<String, dynamic> params]);

  // PATCH /:id
  // Modifies a resource. Clients can submit only the data
  // they want to change, and the corresponding resource will
  // have only those fields changed. This endpoint should return
  // the modified resource.
  @override
  Future<Map<String, dynamic>> modify(String id, Map<String, dynamic> data, [Map<String, dynamic> params]);

  // POST /:id
  // Overwrites a resource. The existing resource is completely
  // replaced by the new data. This endpoint should return the
  // new resource.
  @override 
  Future<Map<String, dynamic>> update(String id, Map<String, dynamic> data, [Map<String, dynamic> params]);

  // DELETE /:id
  // Deletes a resource. This endpoint should return the
  // deleted resource.
  @override
  Future<Map<String, dynamic>> remove(String id, [Map<String, dynamic> params]);
}
```

There are meta-methods that default to delegating to the above:

* `findOne`
* `readMany`

You can override these for your service, if it will improve performance.

### Service Parameters and Middleware

You might notice that each service method accepts an optional `Map` of parameters. When accessed via HTTP (i.e., not over Websockets), `req.query` or `req.bodyAsMap` is passed here (`query` for `index`, `read` and `delete`, `bodyAsMap` for `create`, `update` and `modify`). To pass custom parameters to a service, you should create a middleware to do so. `@Middleware` annotations can be prepended to service classes or service methods. For example, the following will pass `foo='bar'` to every method in the service:

```dart
Future<bool> myMiddleware(RequestContext req, res) async {
  req.queryParameters['foo'] = 'bar';
  return true;
}

@Middleware(const [myMiddleware])
class MyService extends Service {
  // Responds with "['bar']"
  @override index([Map params]) async => [params['query']['foo']];
}
```

Additionally, when accessed by a client, `params` will contain a field called `provider`.

```dart
class MyService extends Service {
  @override
  create(data, [Map params]) async {
    if (params == null || params['provider'] == null) {
       // Accessed via server
    }
  }
}
```

`provider` will be a `Providers` class, whose `String via` will tell you where the service is being accessed from, i.e. `'rest'`, `'graphql'` or `'websocket'`.

### Mounting Services

As mentioned above, services extend `Routable`, so you can simply `app.use()` them. You can also supplement them with additional routes or middleware, placed *before* the mounting of a service:

```dart
app.get("/user/:id/todos", ioc((id) => fetchUserTodos(id))));

// Another way to apply a middleware to a service
app.all("/user/*", [someMiddleware], middleware: ['some', 'more', 'middleware']);

app.use('/user', TypedService<User>(MongoService(db.collection("users"))));

// Access app services. Returns a HookedService if there is one, otherwise just the plain service.
// Leading and trailing slashes are ignored.
var service = app.findService('user'); // The user service
var service = app.service<String, Map<String, dynamic>>('secret'); 
```

## Additional Notes

Important things to consider when writing your own service:

* [mongo](https://github.com/dukefirehawk/angel/tree/master/packages/mongo/lib/mongo_service.dart) is a good reference implementation]
* Services need only worry about handling `Map`s. Object serialization should be handled by `angel3_serialize`, another serializer, or `TypedService`.
* Allowing users to query the service via query string is optional (see `allowQuery`)
* Allowing users to remove all entries is **optional**, and should be disabled by default
  * `DELETE /null` should trigger an evaluation of `allowRemoveAll`
  * `Service.toId` will return `null` in these cases
* Always return the most recent representation of the data
  * After `remove`, return the old item
  * After modify/update, return what the item looks like in the database
* `modify` and `update` are **not** interchangeable!
  * `modify` merges changes into an existing item
  * `update` **overwrites** an existing item
  * BOTH should create an item with the given ID if it does not already exist


# Testing

* [Testing](#testing)
  * [`connectTo(...)`](#connectto)
  * [`isJson(..)`](#isjson)
  * [`hasStatus(...)`](#hasstatus)
  * [More Matchers...](#more-matchers)
* [Next Up...](#next-up)

## Testing

Dart already has fantastic testing support, through a library of [testing helpers](https://github.com/dukefirehawk/angel/tree/master/packages/test) that will make test writing faster. The following functions are exported by [`package:angel3_test`](https://github.com/dukefirehawk/angel/tree/master/packages/test), and will make your testing much easier.

### connectTo

[Full definition](https://pub.dev/documentation/angel3_test/latest/angel3_test/connectTo.html)

This function will start `app` on an available port, and return a `TestClient` instance (based on [`package:angel3_client`](https://github.com/dukefirehawk/angel/tree/master/packages/client)) configured to send requests to the server. The client also supports session manipulation.

```dart
void main() {
  TestClient client;

  setUp(() async {
    client = await connectTo(myApp);
  });

  // Shut down server, and cancel pending requests
  tearDown(() => client.close());

  test('hello', () async {
    // The server URL is automatically prepended to paths.
    // This returns an http.Response. :)
    var response = await client.get('/hello');
  });
}
```

### isJson

A `Matcher` that asserts that the given `http.Response` equals `value` when decoded as JSON. This uses `test.equals` internally, so anything that would pass that matcher passes this one.

### hasStatus

A `Matcher` that asserts the given `http.Response` has the given `status` code.

### More Matchers

The complete set of `angel3_test` Matchers can be found [here](https://pub.dev/documentation/angel3_test/latest/angel3_test/angel_test-library.html).

## Next Up

1. Find out how to [handle errors](/under-the-hood/error-handling) in an Angel3 application.
2. Learn how to use the handy [Angel3 CLI](https://github.com/dukefirehawk/angel3-cli).


# Error Handling

* [Error Handling](#error-handling)
* [Next Up...](#next-up)

## Error Handling

Error handling is one of the most important concerns in building Web applications. The easiest way to throw an HTTP exception is to actually `throw` one. Angel3 provides an `AngelHttpException` class to take care of this.

```dart
app.get('/this-page-does-not-exist', (req, res) async {
  // 404 Not Found
  throw AngelHttpException.notFound();
});
```

Of course, you will probably want to handle these errors, and potentially render views upon catching them.

Fortunately, Angel3 runs every request in a `try`/`catch`, and gracefully intercepts exceptions. This enables Angel3 to catch errors on every request, and not crash the server. Unhandled errors are wrapped in instances of `AngelHttpException`, which can be handled as follows.

You can also turn on the `useZone` flag in `AngelHttp` or another driver (i.e. HTTP/2) to run each request in its own `Zone`, though by Angel3, this is no longer necessary.

To provide custom error handling logic:

```dart
// Typically, you want to preserve the old error handler, unless you are
// completely replacing the functionality.
var oldErrorHandler = app.errorHandler;

app.errorHandler = (e, req, res) {
  if (someCondition || req.accepts('text/html', strict: true)) {
    // Do something else special...
  } else {
    // Otherwise, use the default functionality.
    return oldErrorHandler(e, req, res);
  }
}
```

## Next Up

Congratulations! You have completed the basic Angel3 tutorials. Take what you've learned on a spin in a small side project, and then move on to learning about [services](/under-the-hood/service-basics).


# Pattern Matching and Parameter

`package:angel3_framework` has nice support for injecting values from HTTP headers, query string, and session/cookie values, as well as pattern-matching for request handlers.

These act as a clean shorthand for commonly-used functionality.

Here is a simple example of each of them in action:

```dart
app.get('/cookie', ioc((@CookieValue('token') String jwt) {
    return jwt;
}));

app.get('/header', ioc((@Header('x-foo') String header) {
    return header;
}));

app.get('/query', ioc((@Query('q') String query) {
    return query;
}));

app.get('/session', ioc((@Session('foo') String foo) {
    return foo;
}));

app.get('/match', ioc((@Query('mode', match: 'pos') String mode) {
    return 'YES $mode';
}));

app.get('/match', ioc((@Query('mode', match: 'neg') String mode) {
    return 'NO $mode';
}));

app.get('/match', ioc((@Query('mode') String mode) {
    return 'DEFAULT $mode';
}));
```

## `@Header()`

A simple parameter annotation to inject the value of a sent HTTP header. Throws a 400 if the header is absent.

## `@Query()`

Searches for the value of a query parameter.

## `@Session()`

Fetches a value from the session.

## `@CookieValue()`

Gets the value of a cookie.

## `@Parameter()`

The base class driving the above matchers.

Supports:

* `defaultValue`
* `required`
* custom `error` message

<https://pub.dev/documentation/angel3_framework/latest/angel3_framework/Parameter-class.html>


# Angel Framework Migration


# Angel 2.x.x to Angel3


# Rationale - Why a new Version?

Starting with Dart SDK 2.12.0, NNBD support becomes mandatory in most of the packages. In order to keep up, Angel3 framework has to undergo a major refactoring to support NNBD.


# 3.0.0 Migration Guide

**WARNING**, backup your existing code before proceeding with migration as the process cannot be reversed. Angel project can be upgraded to Angel3 by following the steps below:

1. Run `dart pub outdated --mode=null-safety`. Make sure all the packages **except** `angel_*` are upgradable.
2. Check that all `angel_*` packages can be upgraded by referring to [Migrated Angel3 Packages](https://github.com/dukefirehawk/angel/wiki/Migrated-Angel3-Packages).
3. Upgrade all `angel_*` packages manually in `pubspec.yml` by referring to [NNDB Basic Starter Template](https://github.com/dukefirehawk/boilerplates/blob/basic-sdk-2.12.x_nnbd/pubspec.yaml) or [NNDB ORM Starter Template](https://github.com/dukefirehawk/boilerplates/blob/orm-sdk-2.12.x_nnbd/pubspec.yaml)
4. Run `dart pub upgrade --null-safety` to upgrade the rest of the packages automatically.
5. Run `dart migrate` to do the migration.
6. Fix and resolve NNBD related warnings and errors in the code.
7. Replace all `angel_*` packages in `pubspec.yml` with `angel3_*` equivalent by referring to [Migrated Angel3 Packages](https://github.com/dukefirehawk/angel/wiki/Migrated-Angel3-Packages).
8. Fix and resolve import errors in your project by updating them to `angel3_*` packages.


# Angel 1.x.x to 2.x.x


# 2.0.0 Migration Guide

Based on [this discussion](https://github.com/angel-dart/angel/issues/49).

Based on the changelog, up to `1.1.0`: <https://pub.dartlang.org/packages/angel_framework/versions/1.1.1#-changelog-tab->

## Main Points

* `angel_diagnostics` is deprecated - instead just pass a `Logger` and set it as `app.logger`.
* Removed `AngelFatalError`, and subsequently `fatalErrorStream`.
  * Errors are automatically create `500`. Set `app.logger` to see output.
  * `angel_errors` is no longer useful.
* Removed all `@deprecated` members.
* Removed @Hooked, beforeProcessed, and afterProcessed.
* Made injections in RequestContext private.
* Renamed properties in AngelBase to configuration.
* Added support for pattern matching and other injections via `@Parameter()`
* Officially deprecated properties in Angel.
* Fixed a bug where cached routes would not heed the request method. #173
* Reworked error handling logic; now, errors will not automatically default to sending JSON.
* Removed the onController stream from Angel.
* Controllers now longer use call, which has now been renamed to configureServer.

### Notes

Aside from these points, there are several things to note.

Migration in itself will be pretty easy to achieve. Plugins and services haven't really changed, it's just the HTTP server itself.

## What should I use instead of `X`?

In 1.1.0, the following were completely removed:

* `Angel.after`,
* `Angel.before`
* `Angel.justBeforeStart`
* `Angel.justBeforeStop`
* `Angel.fatalErrorStream`
  * There is no replacement for `before`/`after`. This way, it is easier to keep track of the order request handlers run. responseFinalizers are still in place.
  * `justBeforeStart`, `justBeforeStop` => `startupHooks`, `shutdownHooks`
  * `fatalErrorStream` is no longer necessary; you can just set `app.errorHandler`. Fatal errors will be wrapped in a 500 response.

## How should I define global middleware?

`app.use((req, res) => ...)`

Much cleaner in `1.1.0`. 😄


# Packages


# Databases


# Templates and Views


# Resources


