31.0.0 • Published 5 days ago

@financial-times/n-express v31.0.0

Weekly downloads
1,468
License
-
Repository
-
Last release
5 days ago

n-express Circle CI Coverage Status GitHub release

Express, slightly enhanced with extra functions and common middleware for FT.com apps.

npm install -S @financial-times/n-express

Usage

Import n-express, and initialise it with some options:

const nExpress = require('@financial-times/n-express');

const app = nExpress({
	// options
});

The nExpress function returns an Express app object.

App init options

Passed in to nExpress, these (Booleans defaulting to false unless otherwise stated) turn on various optional features

Mandatory

  • systemCode - allows the application to communicate its Biz Ops code to other services.

Optional

  • withBackendAuthentication - Boolean, defaults to true - if there is a FT_NEXT_BACKEND_KEY[_OLD] env variable, the app will expect requests to have an equivalent FT-Next-Backend-Key[-Old] header; this turns off that functionality. Backend authentication is required for applications serving traffic that should only come via the Fastly -> Preflight -> Router request routing. An example of why is the Next Article application, if this didn't have backend authentication enabled you would be able to view articles via the heroku application url as it wouldn't be protected by barriers which are handled within Fastly and Preflight.
  • withFlags - decorates each request with flags as res.locals.flags
  • withConsent - decorates each request with the user's consent preferences as res.locals.consent
  • withSentry - adds Sentry error handling, both as an Express error handler and an uncaught exception handler. Defaults to true. If you disable Sentry then you must catch uncaught exceptions yourself; the best-supported way to do this is with the Reliability Kit crash-handler.
  • withServiceMetrics - instruments fetch to record metrics on services that the application uses. Defaults to true
  • withAnonMiddleware- adds middleware that converts headers related to logged in status in to a res.locals.anon model
  • healthChecks Array - an array of healthchecks to serve on the /__health path (see 'Healthchecks' section below)
  • healthChecksAppName String - the name of the application, output in the /__health JSON. This defaults to Next FT.com <appname> in <region>.
  • graphiteName String - the app's name in Graphite, for formatting queries. Defaults to the systemCode.

Static properties and methods

  • Router - express.Router
  • static - express.static middleware
  • metrics - next-metrics instance
  • flags - n-flags-client instance
  • getAppContainer() - returns an object: - app: the express app instance - meta: object containing the name, description and directory of the app - addInitPromise(): function for adding additional promises to wait for before allowing the app to accept traffic

Cache control

Several useful cache control header values are available as constants on responses:

	res.FT_NO_CACHE = 'max-age=0, no-cache, must-revalidate';
	res.FT_NO_CACHE_PRIVATE = 'max-age=0, no-cache, no-store, must-revalidate, private';
	res.FT_SHORT_CACHE = 'max-age=600, stale-while-revalidate=60, stale-if-error=86400';
	res.FT_HOUR_CACHE = 'max-age=3600, stale-while-revalidate=60, stale-if-error=86400';
	res.FT_DAY_CACHE = 'max-age=86400, stale-while-revalidate=60, stale-if-error=86400';
	res.FT_WEEK_CACHE = 'max-age=604800, stale-while-revalidate=60, stale-if-error=259200';
	res.FT_LONG_CACHE = 'max-age=86400, stale-while-revalidate=60, stale-if-error=259200';

Cache varying

Various vary headers are set by default (ft-flags, ft-anonymous-user, ft-edition, Accept-Encoding as of Apr 2016 ) as they are required for most responses - the user experience will break if they are not. To control these a few additional methods are provided

  • res.unvary('My-Header') - use if your response definitely doesn't need to vary on one of the standard vary headers e.g. .rss probably doesn't need to vary on ft-edition
  • res.unvaryAll('wrapper') removes all headers included by default for use by the usual next page layout... ideal for serving html fragments, json etc.
  • res.unvaryAll() - remove all vary headers. Do not use lightly!!!
  • res.vary('My-Header') - add to the list of vary headers

next-metrics

As next-metrics must be a singleton to ensure reliable reporting, it is exported at require('@financial-times/n-express').metrics. To send metrics under a variant app name (e.g. a canary app) set the environment variable FT_APP_VARIANT.

Other enhancements

  • fetch is added as a global using isomorphic-fetch
  • Errors are sent to sentry using n-raven
  • Instrumentation of system and http (incoming and outgoing) performance using Next Metrics
  • Anti-search engine GET /robots.txt (possibly might need to change in the future)
  • Exposes various bits of metadata about the app (e.g. name, version, env, isProduction) to templates (via res.locals) and the outside world (via {appname}/__about.json)

Health checks

For an example set of health check results, see ft-next-health-eu.herokuapp.com/__health and ft-next-health-us.herokuapp.com/__health. For testing health checks, the Health Status Formatter extension for Google Chrome is recommended.

Health checks can be tested for failures of a specific degree of severity by appending the severity number to the health check URL. This is particularly useful for setting up fine-grained alerting. For example, if on next.ft.com a severity level 2 health check were failing:

https://ft-next-health-eu.herokuapp.com/__health.1 would return HTTP status 200 https://ft-next-health-eu.herokuapp.com/__health.2 would return HTTP status 500 https://ft-next-health-eu.herokuapp.com/__health.3 would return HTTP status 500

Each health check must have a getStatus() property, which returns an object meeting the specifications of the FT Health Check Standard and the FT Check Standard. This might look roughly like the following example:

Note also that it is now required for the JSON returned at the /__health endpoint to contain the system code. To ensure that this happens, please ensure that the systemCode property of the express app init options has been supplied. See the 'App init options' section above.

var exampleHealthCheck = {
	getStatus: () => {
		return {
			name: 'Some health check',
			ok: true,
			checkOutput: 'Everything is fine',
			lastUpdated: new Date(),
			panicGuide: 'Don\'t panic',
			severity: 3,
			businessImpact: "Some specific feature will fail",
			technicalSummary: "Doesn\'t actually check anything, just an example"
		};
	}
}

Troubleshooting

Testing with flags

If you’re using flags and testing with mocha, you’ll need to expose listen in your app:

module.exports.listen = app.listen(port);

And in your tests, add this:

before(function() {
	return app.listen;
});

This’ll make sure your tests wait for flags to be ready.

Writing tests with n-express in other apps

If you're including n-express in your integration tests, you can add this:

after(() => {
  app.close()
})

to stop the tests from hanging from scheduled healthchecks

31.0.0

5 days ago

30.5.0

28 days ago

30.4.0

1 month ago

30.3.0

2 months ago

30.2.0

2 months ago

30.1.0

2 months ago

30.0.1

2 months ago

30.0.0

3 months ago

29.0.0

4 months ago

28.4.0

4 months ago

28.3.0

6 months ago

27.5.0

11 months ago

28.2.0

6 months ago

27.7.0

10 months ago

27.6.0

10 months ago

28.1.0

6 months ago

28.1.3

6 months ago

28.1.1

6 months ago

28.1.2

6 months ago

28.0.0

10 months ago

28.0.1

10 months ago

28.0.4

8 months ago

28.0.5

7 months ago

28.0.2

9 months ago

28.0.3

8 months ago

27.4.0

11 months ago

27.1.0-beta

1 year ago

27.0.2

1 year ago

27.0.1

1 year ago

26.3.14

1 year ago

26.3.15

1 year ago

27.3.0

12 months ago

27.2.0

1 year ago

26.3.12

1 year ago

26.3.13

1 year ago

26.3.11

1 year ago

26.3.9

1 year ago

26.3.8

1 year ago

26.3.7

1 year ago

26.3.6

1 year ago

26.3.5

2 years ago

26.3.4

2 years ago

26.3.3

2 years ago

26.3.2

2 years ago

26.3.1

2 years ago

26.1.2

2 years ago

26.1.1

2 years ago

26.1.0

2 years ago

25.3.2

2 years ago

26.0.0

2 years ago

26.3.0

2 years ago

26.2.0

2 years ago

23.4.0

2 years ago

25.1.1

2 years ago

25.1.0

2 years ago

23.5.1

2 years ago

23.5.0

2 years ago

25.0.0

2 years ago

24.2.0

2 years ago

25.3.1

2 years ago

25.3.0

2 years ago

25.2.0

2 years ago

25.2.1

2 years ago

24.1.0

2 years ago

23.3.0

2 years ago

24.0.0

2 years ago

23.1.0

2 years ago

23.2.0

2 years ago

23.0.3

2 years ago

23.0.0

2 years ago

23.0.2

2 years ago

23.0.1

2 years ago

22.4.4

2 years ago

22.4.3

2 years ago

22.4.2

2 years ago

22.4.1

2 years ago

22.5.0

2 years ago

22.2.0

2 years ago

22.3.0

2 years ago

22.1.8

3 years ago

22.1.7

3 years ago

22.1.6

3 years ago

22.1.5

3 years ago

22.1.4

3 years ago

22.1.3

3 years ago

22.1.2

3 years ago

22.1.1

3 years ago

22.1.0

3 years ago

21.0.18

3 years ago

22.0.1

3 years ago

21.0.17

3 years ago

21.0.16

3 years ago

21.0.15

3 years ago

21.0.14

3 years ago

21.0.12

3 years ago

21.0.13

3 years ago

22.0.0

3 years ago

21.0.10

3 years ago

21.0.11

3 years ago

21.0.9

3 years ago

21.0.8

3 years ago

21.0.6

3 years ago

21.0.7

3 years ago

21.0.5

3 years ago

21.0.4

3 years ago

21.0.3

3 years ago

21.0.2

3 years ago

21.0.1

3 years ago

21.0.0

3 years ago

20.0.2

3 years ago

20.0.1

4 years ago

20.0.0

4 years ago

19.23.4

4 years ago

19.23.3

4 years ago

19.23.2

4 years ago

19.23.1

4 years ago

19.23.0

4 years ago

19.22.16

4 years ago

19.22.15

4 years ago

19.22.14

4 years ago

19.22.13

4 years ago

19.22.12

4 years ago

19.22.11

4 years ago

19.22.9

4 years ago

19.22.8

4 years ago

19.22.7

4 years ago

19.22.6

4 years ago

19.22.5

4 years ago

19.22.4

4 years ago

19.22.3

5 years ago

19.22.2

5 years ago

19.22.1

5 years ago

19.22.0

5 years ago

19.21.4

5 years ago

19.21.3

5 years ago

19.21.1

5 years ago

19.21.0

5 years ago

19.20.2

6 years ago

19.20.1

6 years ago

19.20.0

6 years ago

19.20.0-beta.1

6 years ago

19.19.4

6 years ago

19.19.3

6 years ago

19.19.2

6 years ago

19.19.1

6 years ago

19.19.0

6 years ago

19.19.0-beta.1

6 years ago

19.18.3

6 years ago

19.18.2

6 years ago

19.18.1

6 years ago

19.18.0

6 years ago

19.17.0

6 years ago

19.17.0-beta.2

6 years ago

19.17.0-beta.1

6 years ago

19.16.0

6 years ago

19.16.0-beta.1

6 years ago

19.15.1

6 years ago

19.15.0

6 years ago

19.14.6

6 years ago

19.14.5

6 years ago

19.14.4

6 years ago

19.14.3

6 years ago

19.14.2

6 years ago

19.14.1

6 years ago

19.14.0

6 years ago

19.13.5

6 years ago

19.13.4

6 years ago

19.13.3

6 years ago

19.13.2

6 years ago

19.13.1

6 years ago

19.13.0

6 years ago

19.12.2

6 years ago

1.19.2

6 years ago

19.12.1

6 years ago

19.12.0

6 years ago

19.11.1-beta.2

6 years ago

19.11.0

6 years ago

19.10.1

6 years ago

19.10.0

6 years ago

19.9.0

6 years ago

19.9.0-beta.2

6 years ago

19.9.0-beta.1

6 years ago

19.8.0

6 years ago

19.7.0

6 years ago

19.6.1

6 years ago

19.6.0

6 years ago

19.5.0-beta.1

6 years ago

19.5.0

6 years ago

19.4.3

7 years ago

19.4.2

7 years ago

19.4.1

7 years ago

19.3.3

7 years ago

19.3.2

7 years ago

19.3.1

7 years ago

19.3.0

7 years ago

19.3.0-beta.3

7 years ago

19.3.0-beta.2

7 years ago

19.3.0-beta.1

7 years ago

19.2.5

7 years ago

19.2.4

7 years ago

19.2.3

7 years ago

19.2.2

7 years ago

19.2.1

7 years ago

19.2.0

7 years ago

19.1.0

7 years ago

19.0.5

7 years ago

19.0.4

7 years ago

19.0.1

7 years ago

19.0.0

7 years ago

18.1.2

7 years ago

18.1.0

7 years ago

18.0.0

7 years ago

17.22.0

7 years ago

17.21.5

7 years ago

17.21.4

7 years ago

17.21.3

7 years ago

17.21.2

7 years ago

17.21.1

7 years ago

17.21.0

7 years ago

17.20.3

7 years ago

17.20.2

7 years ago

17.20.1

7 years ago

17.20.0

7 years ago

17.19.2

7 years ago

17.19.1

7 years ago

17.19.0

7 years ago

17.18.0

7 years ago

17.17.0

7 years ago

17.16.3

7 years ago

17.16.2

8 years ago

17.16.1

8 years ago

17.16.0

8 years ago

17.15.5

8 years ago

17.15.4

8 years ago

17.15.3

8 years ago

17.15.2

8 years ago

17.15.1

8 years ago

17.15.0

8 years ago

17.14.0

8 years ago

17.13.0

8 years ago

17.12.3

8 years ago

17.12.2

8 years ago

17.12.1

8 years ago

17.12.0

8 years ago

17.11.0

8 years ago

17.10.0

8 years ago

17.9.0

8 years ago

17.8.2

8 years ago

17.8.1

8 years ago

17.8.0

8 years ago

17.7.0

8 years ago

17.6.4

8 years ago

17.6.3

8 years ago

17.6.2

8 years ago

17.6.1

8 years ago

17.6.0

8 years ago

17.5.4

8 years ago

17.5.3

8 years ago

17.5.2

8 years ago

17.5.1

8 years ago

17.5.0

8 years ago

17.4.0

8 years ago

17.3.0

8 years ago

17.2.3

8 years ago

17.2.1

8 years ago

17.2.0

8 years ago

17.1.1

8 years ago

17.1.0

8 years ago

17.0.4

8 years ago

17.0.3

8 years ago

17.0.2

8 years ago

17.0.1

8 years ago

17.0.0

8 years ago

16.15.10

8 years ago

16.15.9

8 years ago

16.15.8

8 years ago

16.15.7

8 years ago

16.15.6

8 years ago

16.15.5

8 years ago

16.15.4

8 years ago

16.15.3

8 years ago

16.15.2

8 years ago

16.15.1

8 years ago

16.15.0

8 years ago

16.14.2

8 years ago

16.14.1

8 years ago

16.14.0

8 years ago

16.13.0

8 years ago

16.12.3

8 years ago

16.12.2

8 years ago

16.12.1

8 years ago

16.12.0

8 years ago

16.11.1

8 years ago

16.11.0

8 years ago

16.9.2

8 years ago

16.9.1

8 years ago

16.9.0

8 years ago

16.8.0

8 years ago

16.7.0

8 years ago

16.6.1

8 years ago

16.6.0

8 years ago

16.5.1

8 years ago

16.5.0

8 years ago

16.4.0

8 years ago

16.3.0

8 years ago

16.2.1

8 years ago

16.2.0

8 years ago

16.1.4

8 years ago

16.1.2

8 years ago

16.1.1

8 years ago

16.1.0

8 years ago

16.0.4

8 years ago

16.0.3

8 years ago

16.0.2

8 years ago

16.0.1

8 years ago

16.0.0

8 years ago

15.4.3

9 years ago

15.4.2

9 years ago