[![NPM Version][npm-image]][npm-url]
[![Build Status][build-image]][build-url]

# @pirxpilot/connect

This is a simplified fork of [connect] with some dependencies removed.
Connect is an extensible HTTP server framework for [node](http://nodejs.org) using "plugins" known as _middleware_.

```js
import connect from 'connect';
import { createServer } from 'http';
import compression from 'compression';
import cookieSession from 'cookie-session';
import bodyParser from 'body-parser';

const app = connect();

// gzip/deflate outgoing responses
app.use(compression());

// store session state in browser cookie
app.use(cookieSession({
    keys: ['secret1', 'secret2']
}));

// parse urlencoded request bodies into req.body
app.use(bodyParser.urlencoded({ extended: false }));

// respond to all requests
app.use((req, res) => {
  res.end('Hello from Connect!\n');
});

// create node.js http server and listen on port
createServer(app).listen(3000);
```

## Getting Started

Connect is a simple framework to glue together various "middleware" to handle requests.

### Install Connect

```sh
$ npm install connect
```

### Create an app

The main component is a Connect "app". This will store all the middleware
added and is, itself, a function.

```js
const app = connect();
```

### Use middleware

The core of Connect is "using" middleware. Middleware are added as a "stack"
where incoming requests will execute each middleware one-by-one until a middleware
does not call `next()` within it.

```js
app.use((req, res, next) => {
  // middleware 1
  next();
});
app.use((req, res, next) => {
  // middleware 2
  next();
});
```

### Mount middleware

The `.use()` method also takes an optional path string that is matched against
the beginning of the incoming request URL. This allows for basic routing.

```js
app.use('/foo', (req, res, next) => {
  // req.url starts with "/foo"
  next();
});
app.use('/bar', (req, res, next) => {
  // req.url starts with "/bar"
  next();
});
```

### Error middleware

There are special cases of "error-handling" middleware. There are middleware
where the function takes exactly 4 arguments. When a middleware passes an error
to `next`, the app will proceed to look for the error middleware that was declared
after that middleware and invoke it, skipping any error middleware above that
middleware and any non-error middleware below.

```js
// regular middleware
app.use((req, res, next) => {
  // i had an error
  next(new Error('boom!'));
});

// error middleware for errors that occurred in middleware
// declared before this
app.use((err, req, res, next) => {
  // an error occurred!
});
```

### Create a server from the app

The last step is to actually use the Connect app in a server. The `.listen()` method
is a convenience to start a HTTP server (and is identical to the `http.Server`'s `listen`
method in the version of Node.js you are running).

```js
const server = app.listen(port);
```

The app itself is really just a function with three arguments, so it can also be handed
to `.createServer()` in Node.js.

```js
import { createServer } from 'http';

const server = createServer(app);
```

## API

The Connect API is very minimalist, enough to create an app and add a chain
of middleware.

When the `connect` module is required, a function is returned that will construct
a new app when called.

```js
// import module
import connect from 'connect';

// create app
const app = connect();
```

### app(req, res[, next])

The `app` itself is a function. This is just an alias to `app.handle`.

### app.handle(req, res[, out])

Calling the function will run the middleware stack against the given Node.js
http request (`req`) and response (`res`) objects. An optional function `out`
can be provided that will be called if the request (or error) was not handled
by the middleware stack.

### app.listen([...])

Start the app listening for requests. This method will internally create a Node.js
HTTP server and call `.listen()` on it.

This is an alias to the `server.listen()` method in the version of Node.js running,
so consult the Node.js documentation for all the different variations. The most
common signature is [`app.listen(port)`](https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_server_listen_port_hostname_backlog_callback).

### app.use(fn)

Use a function on the app, where the function represents a middleware. The function
will be invoked for every request in the order that `app.use` is called. The function
is called with three arguments:

```js
app.use((req, res, next) => {
  // req is the Node.js http request object
  // res is the Node.js http response object
  // next is a function to call to invoke the next middleware
});
```

In addition to a plan function, the `fn` argument can also be a Node.js HTTP server
instance or another Connect app instance.

### app.use(route, fn)

Use a function on the app, where the function represents a middleware. The function
will be invoked for every request in which the URL (`req.url` property) starts with
the given `route` string in the order that `app.use` is called. The function is
called with three arguments:

```js
app.use('/foo', (req, res, next) => {
  // req is the Node.js http request object
  // res is the Node.js http response object
  // next is a function to call to invoke the next middleware
});
```

In addition to a plan function, the `fn` argument can also be a Node.js HTTP server
instance or another Connect app instance.

The `route` is always terminated at a path separator (`/`) or a dot (`.`) character.
This means the given routes `/foo/` and `/foo` are the same and both will match requests
with the URLs `/foo`, `/foo/`, `/foo/bar`, and `/foo.bar`, but not match a request with
the URL `/foobar`.

The `route` is matched in a case-insensitive manor.

In order to make middleware easier to write to be agnostic of the `route`, when the
`fn` is invoked, the `req.url` will be altered to remove the `route` part (and the
original will be available as `req.originalUrl`). For example, if `fn` is used at the
route `/foo`, the request for `/foo/bar` will invoke `fn` with `req.url === '/bar'`
and `req.originalUrl === '/foo/bar'`.

## People

The Connect project would not be the same without all the people involved.

The original author of Connect is [TJ Holowaychuk](https://github.com/tj)

The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson)

[List of all contributors](https://github.com/senchalabs/connect/graphs/contributors)

## License

[MIT](LICENSE)

[connect]: htps://github.com/sencha/connect
[npm-image]: https://img.shields.io/npm/v/@pirxpilot/connect
[npm-url]: https://npmjs.org/package/@pirxpilot/connect
[build-image]: https://img.shields.io/github/actions/workflow/status/pirxpilot/connect/check.yaml?branch=main
[build-url]: https://github.com/pirxpilot/connect/actions/workflows/check.yaml
