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
  1. Advanced

Writing a Plugin

PreviousAdvanced

Last updated 6 years ago

Writing a is easy. You can provide plug-ins as either functions, or classes:

AngelConfigurer awesomeify() => (Angel app) async {
  app.before.add((req, res) async {
    req.write('This request was intercepted by an awesome plug-in.');
    return false;
  });
}

class MyAwesomePlugin extends AngelPlugin {
  @override
  Future call(Angel app) async {
    app.responseFinalizers.add((req, res) async {
      res.headers['Be-Awesome'] = 'All the time';
    });
  }
}

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 Angel API's whenever possible. This will help your plugin resist breaking change in the future.

  • Try to get it .

  • Plugins should generally be small.

  • Plugins should NEVER modify app configuration!!!

    • i.e. Do NOT set app.lazyParseBodies, app.storeOriginalBuffer, etc.

  • Stay away from req.io and res.io if possible. Using these will doom your plugin to a life of only working on HTTP servers. Future versions of Angel may be server-agnostic, and this will keep your plugin firmly lodged in the past.

  • If your plugin is development-only or production-only, it should automatically configure itself. Prefer to manually checking the environment for ANGEL_ENV.

  • Use req.lazyBody(), req.lazyFiles(), etc. if you are running in an async context. Otherwise, your plugin may crash applications that lazy-parse request bodies.

  • If you use req.lazyQuery(), refrain from using forceParse. Never force any additional side effects on the user.

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

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

  // Easier than:
  app.responseFinalizers.add(compress('gzip', GZIP));
}

Finally, your plugin should expose common options in a simple way. For example, the (deprecated) plugin has a shortcut function, gzip, to set up GZIP compression, whereas for any other codec, you would manually have to specify additional options.

compress
plug-in
added to main organization
app.isProduction
Guidelines