Git Product home page Git Product logo

koa's Introduction

Koa middleware framework for nodejs

gitter NPM version build status Test coverage OpenCollective Backers OpenCollective Sponsors PR's Welcome

Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Koa's middleware stack flows in a stack-like manner, allowing you to perform actions downstream then filter and manipulate the response upstream.

Only methods that are common to nearly all HTTP servers are integrated directly into Koa's small ~570 SLOC codebase. This includes things like content negotiation, normalization of node inconsistencies, redirection, and a few others.

Koa is not bundled with any middleware.

Installation

Koa requires node v12.17.0 or higher for ES2015 and async function support.

$ npm install koa

Hello Koa

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);

Getting started

  • Kick-Off-Koa - An intro to Koa via a set of self-guided workshops.
  • Guide - Go straight to the docs.

Middleware

Koa is a middleware framework that can take two different kinds of functions as middleware:

  • async function
  • common function

Here is an example of logger middleware with each of the different functions:

async functions (node v7.6+)

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

Common function

// Middleware normally takes two parameters (ctx, next), ctx is the context for one request,
// next is a function that is invoked to execute the downstream middleware. It returns a Promise with a then function for running code after completion.

app.use((ctx, next) => {
  const start = Date.now();
  return next().then(() => {
    const ms = Date.now() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
  });
});

Koa v1.x Middleware Signature

The middleware signature changed between v1.x and v2.x. The older signature is deprecated.

Old signature middleware support will be removed in v3

Please see the Migration Guide for more information on upgrading from v1.x and using v1.x middleware with v2.x.

Context, Request and Response

Each middleware receives a Koa Context object that encapsulates an incoming http message and the corresponding response to that message. ctx is often used as the parameter name for the context object.

app.use(async (ctx, next) => { await next(); });

Koa provides a Request object as the request property of the Context.
Koa's Request object provides helpful methods for working with http requests which delegate to an IncomingMessage from the node http module.

Here is an example of checking that a requesting client supports xml.

app.use(async (ctx, next) => {
  ctx.assert(ctx.request.accepts('xml'), 406);
  // equivalent to:
  // if (!ctx.request.accepts('xml')) ctx.throw(406);
  await next();
});

Koa provides a Response object as the response property of the Context.
Koa's Response object provides helpful methods for working with http responses which delegate to a ServerResponse .

Koa's pattern of delegating to Node's request and response objects rather than extending them provides a cleaner interface and reduces conflicts between different middleware and with Node itself as well as providing better support for stream handling. The IncomingMessage can still be directly accessed as the req property on the Context and ServerResponse can be directly accessed as the res property on the Context.

Here is an example using Koa's Response object to stream a file as the response body.

app.use(async (ctx, next) => {
  await next();
  ctx.response.type = 'xml';
  ctx.response.body = fs.createReadStream('really_large.xml');
});

The Context object also provides shortcuts for methods on its request and response. In the prior examples, ctx.type can be used instead of ctx.response.type and ctx.accepts can be used instead of ctx.request.accepts.

For more information on Request, Response and Context, see the Request API Reference, Response API Reference and Context API Reference.

Koa Application

The object created when executing new Koa() is known as the Koa application object.

The application object is Koa's interface with node's http server and handles the registration of middleware, dispatching to the middleware from http, default error handling, as well as configuration of the context, request and response objects.

Learn more about the application object in the Application API Reference.

Documentation

Troubleshooting

Check the Troubleshooting Guide or Debugging Koa in the general Koa guide.

Running tests

$ npm test

Reporting vulnerabilities

To report a security vulnerability, please do not open an issue, as this notifies attackers of the vulnerability. Instead, please email dead_horse, jonathanong, and niftylettuce to disclose.

Authors

See AUTHORS.

Community

Job Board

Looking for a career upgrade?

Backers

Support us with a monthly donation and help us continue our activities.

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site.

License

MIT

koa's People

Contributors

3imed-jaberi avatar dead-horse avatar dependabot[bot] avatar doug-wade avatar fengmk2 avatar fl0w avatar foxandxss avatar fundon avatar ianstormtaylor avatar initial-wu avatar iyuq avatar jamesgeorge007 avatar joehecn avatar jonathanong avatar juliangruber avatar neighborhood999 avatar nickmccurdy avatar pana avatar plasmapower avatar shfshanyue avatar shime avatar stojanovic avatar targos avatar tejasmanohar avatar tinovyatkin avatar tj avatar we11adam avatar yorkie avatar yoshuawuyts avatar zyszys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koa's Issues

don't touch original req/res

would be nice if koa didn't touch the original req/res. since we're building a wrapper around them, i don't see why it would be necessary.

example is:

  /**
   * Set request URL.
   *
   * @api public
   */

  set url(val) {
    this.req.url = val;
  },

Wish it were something else like:

  get url() {
    return this._url || this.req.url
  },

  set url(val) {
    this._url = val
  }

basic auth

does basic auth really need to be in core?

FAQ

with some design decisions etc

yield down

instead of yield next? so used to next() in connect that it mind-fucks me a bit

moar middleware

more common shit, all as wrappers for vanilla node libs when appropriate.

  • common logger
  • compression
  • cookie session
  • db session
  • conditional get
  • jsonp
  • etag
  • directory
  • csrf protection
  • request limits
  • rate limiting
  • favicon
  • methodOverride
  • basicAuth
  • route
  • domains
  • static
  • timeout

more convenience properties

  • this.response.lastModified = Date() - since i'm too lazy to do this.set('Last-Modified', new Date().toUTCString()). plus we can normalize people's date strings.
  • this.response.etag = '12345' - wrap the etag in "s if not already.
  • this.response.link()
  • this.response.location()

most of the other stuff i can think of are already handled by higher level stuff. or people won't use. if you don't have any opinions on these, i will implement them after you implement this.response and this.request.

remove qs dependency

i personally don't like qs. would be nice if you removed it as a dep and used the native querystring module in core, then moved qs to a separate repo.

consider domain support (optional?)

seems like we can't really wrap just one stream so we may want to consider this, knocks a good 1000rps off but eh. seems a little tricky to do with middleware since we have to terminate it lower, similar issue to the compress middleware

LICENSE?

update the year to 2013. Also, you should add the repository field to package.json.

consider delegating to ctx.request / ctx.response

In general I don't like this for the average use-case and "hot" methods, but I do prefer this.request.etag to this.get('ETag'), this.request.length, this.response.length, this.response.header etc, but the common cases we have would delegate: this.body = foo == this.response.body = foo. something to think about

app.mixin()

since we will have app.context(), app.request(), and app.response(), i guess we should have something like app.mixin() where you can do:

app.mixin({
  context: {},
  request: {},
  response: {}
})

so you can do with a plugin:

app.mixin(require('koa-context-something'))

maybe app.plugin(). maybe a different, better name. also, an app.inherit(parentapp) would be nice as well, especially if you mount apps.

Why not app.use(generator) ?

Like this

app.use(function *(next) {
    var start = new Date;
    yield next;
    var ms = new Date - start;
    console.log('%s %s - %s', this.method, this.url, ms);
});

Is there a reason for that?

app error handling improvements

right now, app.onerror is added to the the error event listener automatically. what happens if users don't want to use it? doing app.removeListener('event', app.onerror)` is a little annoying. instead i suggest the following:

  • remove app.onerror
  • remove app.outputErrors
  • at the app.callback() stage, warn/throw if no event listeners have been added
  • automatically add the default listener in development
app.callback = function(){
  // ...

  if (!app.listeners('error')) {
    if (this.env === 'development') {
      console.warn('You should add your own error handler.');
      app.on('error', function(err) {
        console.error(err.stack);
      })
    } else if (this.env !== 'test') {
      throw new Error('Add your own error handler!');
    }
  }

  return function(req, res){
  // ..
})

warn if app.context() overwrites another property during development

since we kind of expect developers to attach their own properties to context, it may be nice to warn when a property is overwritten. this is to avoid conflicts with different plugins/extensions/etc. we can also do something like app.context(obj, dontWarnMe) where dontWarnMe is a Boolean and default true during development.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.