Angel
1.x
1.x
  • Introduction
  • Example Projects
  • Awesome Angel
  • 1.1.0 Migration Guide
  • Social
    • Angel on Gitter
    • Angel on Medium
    • Angel on YouTube
  • The Basics
    • Installation & Setup
      • Without the Boilerplate
    • Requests & Responses
    • Dependency Injection
    • Basic Routing
    • Request Lifecycle
    • Middleware
    • Controllers
    • Handling File Uploads
    • Using Plug-ins
    • Rendering Views
    • REST Client
    • Testing
    • Error Handling
    • Pattern Matching and Parameter
    • Command Line
  • Flutter
    • Writing a Chat App
    • Flutter helper widgets
  • Services
    • Service Basics
    • TypedService
    • In-Memory
    • Custom Services
    • Hooks
      • Bundled Hooks
    • Database-Agnostic Relations
    • Database Adapters
      • MongoDB
      • RethinkDB
      • JSON File-based
  • Plug-ins
    • Authentication
    • Configuration
    • Diagnostics & Logging
    • Reverse Proxy
    • Service Seeder
    • Static Files
    • Validation
    • Websockets
    • Server-sent Events
    • Toggle-able Services
  • Middleware/Finalizers
    • CORS
    • Response Compression
    • Security
    • File Upload Security
    • shelf Integration
    • User Agents
    • Pagination
    • Range, If-Range, Accept-Ranges support
  • PostgreSQL ORM
    • Model Serialization
    • Query Builder + ORM
    • Migrations
  • Deployment
    • Running in Isolates
    • Configuring SSL
    • HTTP/2 Support
    • Ubuntu and nginx
    • AppEngine
    • Production Mode
  • Front-end
    • Mustache Templates
    • Jael template engine
      • Github
      • Basics
      • Custom Elements
      • Strict Resolution
      • Directive: declare
      • Directive: for-each
      • Directive: extend
      • Directive: if
      • Directive: include
      • Directive: switch
    • compiled_mustache-based engine
    • html_builder-based engine
    • Markdown template engine
    • Using Angel with Angular
  • Advanced
    • API Documentation
    • Contribute to Angel
    • Scaling & Load Balancing
    • Standalone Router
    • Writing a Plugin
    • Task Engine
    • Hot Reloading
    • Real-time polling
Powered by GitBook
On this page
  • Requests and Responses
  • Return Values
  • Other Parameters
  • Queries, Files and Bodies
  • Next Up...
  1. The Basics

Requests & Responses

PreviousWithout the BoilerplateNextDependency Injection

Last updated 6 years ago

Requests and Responses

Angel is inspired by Express, and such, request handlers in general represent those from Express. Request handlers can be functions, or plain Dart objects (see ). Basic request handlers accept two parameters:

  • - 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.

  • - 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.

Both requests and responses contain a Map of properties that can be filled with arbitrary data and read/modified at any point during the .

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 . Some response methods, such as or automatically close the response.

  • Anything else: Whatever other Dart value you return will be serialized as a response. The default method is to encode responses as JSON, and to do so using reflection (see package:json_god). 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, call 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.

Other Parameters

Request handlers do not even have to be functions at all. You can provide singleton values as request handlers, and they will always be sent to clients without running any functions.

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

  // String will be JSON-encoded
  app.get('/', (req, res) async => "Hello, world!");

  // Access params
  app.get('/:id', (req, res) async => "ID: ${req.params['id']}");

  app.post('/', ["More", "arbitrary", "data"]);

  app.get('/todos/:id', (String id) => fetchTodoById(id));
}

Queries, Files and Bodies

Angel automatically parses multipart/form-data, application/json, and application/x-www-form-urlencoded bodies.

main() {
  // Set this flag to lazy-parse bodies
  app.lazyParseBodies = true;

  app.get('/', () {
    // Requests that don't need the body, never see the body
  });

  app.post('/:id', (req, res) async {
    var body = await req.lazyBody();

    // Same as running:
    await req.parse();
    var body = req.body;
  });
}

req.query can be used without parsing the request body. However, the query string parser in package:body_parser supports advanced queries like the following, so you may consider parsing the body:

// This query string:
// ?foo=bar&bar.baz.foo=hello&bar.world=quux
//
// becomes:
{
  "foo": "bar",
  "bar": {
    "world": "quux",
    "baz": {
      "foo": "hello"
    }
  }
}

For more information, see the API docs:

Next Up...

Request handlers can take other parameters, instead of just a RequestContext and ResponseContext. All parameters will be into a response, whether from , , or .

and are Maps, and are available on each request. is a List of files uploaded to the server.

When you are in production, one way to improve performance is by only parsing request bodies when it is necessary. In such a case, you will have to use , , etc. to access request body information. The request body will only be parsed once.

If you , be sure to use the lazy alternatives.

Now, let's learn about Angel's .

injected
req.injections
req.params
req.properties
req.query
req.body
req.files
lazyBody()
lazyFiles()
write your own plugin
RequestContext
ResponseContext
flexible router
RequestContext
ResponseContext
request lifecycle
res.end()
res.redirect()
res.serialize()
injectSerializer
Requests and Responses
Return Values
Other Parameters
Queries, Files and Bodies
Next Up...
how they are handled