Serving APIs

The Ceptor Gateway has API Gateway functionality on top of all its existing capabilities.

Please read the Gateway Concepts for an overview of its capabilities in general and refer to Gateway Configuration for full details.

When serving APIs, you need to create a Location (see Config - Locations for details) that has its action set to serve APIs.

Let's take an example:

Go to the Gateway Configuration in the menu, and add a new location:

Place it near the top in the gateway list, and save it.

Now, you can go to the locations configuration and change its settings.

Add a condition for when this Location will be called, e.g. if the hostname is api-test.example.com

You can add any other conditions you wish to limit when this location will be triggered.

Go to the location settings, set the "Valid HTTP Methods" to "*" or whichever set of HTTP methods you want to limit it to.

Set the Action to serveapi which is what enables the API Gateway functionality for this location.

Now, save it.

After saving, you will notice that there is a new section available; "API Gateway" - go there to configure the remaining settings:


Select the environment you want to serve APIs for, choose a Rate Limiter and add any API Usage reporters you wish. You can also change the interval between remote API specification reloads (a functionality of a particular API Version where the OpenAPI specification is not stored locally, but retrieved from remote - e.g. when generated using Spring Boot or other frameworks).

Rate Limiter

A rate limiter implementation decides how rate limits are implemented for this location - it is possible to add your own custom rate limiting implementation which you can use, or you can choose one of the defaults.

If no rate limiters are set up, rate limiting (set up on Subscription Plans and Rate Limit Groups) will be ignored.

By default, Ceptor comes with support for these implementations:

Only a single implementation can be used at a time for a given location.

API Usage Reporters

An API Usage plugin reports API usage per call - it stores information about who made the call, when it was made, its response time etc. An API Usage plugin is invoked after the call has completed, and has access to all the information also available for access logging.

You can create your own custom implementations, or use one of the default ones.

If no API Usage reporters are setup, no specific API usage will be reported, and just the regular access log will be used instead.

By default, Ceptor comes with support for these implementations:

Note that multiple API Usage plugins can be configured at a time, so you can store API Usage information e.g. both in the logs, and in elasticsearch.

This is an example of the JSON created by the standard API Usage plugin:

{
	"apiversion.id": "a34a268f-34b1-465c-9327-262c2c69c4d3",
	"api.id": "3fe3ac57-c2da-4ce2-a2bc-25202f62c88b",
	"prettyname": "Hello World (Demonstration APIs) 1",
	"sessionid": "CEPID_AA8BMDowOjA6MDowOjA6MDoxACwCAAABZgeZf-AAAAANS03BgL8QbYIh6e-qCwKtlM9CTkIWwb1OoiDBzYW04fEAAQMB~AAIBMDIADwMwOjA6MDowOjA6MDowOjEAAgSQPQAMBTdGODAAAAAAAAABhQ",
	"apipartner.id": "25df072a-f500-45a9-83eb-5f99c152b5fb",
	"apipartner.name": "Ceptor ApS",
	"apipartner.application.id": "45bc3a53-7308-47e7-887a-21cf75cfe404",
	"apipartner.application.name": "Test App 1",
	"remote.ip": "0:0:0:0:0:0:0:1",
	"remote.port": 36925,
	"request.method": "GET",
	"request.path": "/hello/v1/hello",
	"request.host": "localhost:8443",
	"request.query": "",
	"request.headers": {
		"accept": "application/json",
		"Accept-Language": "da-DK,da;q=0.9,en-US;q=0.8,en;q=0.7",
		"Accept-Encoding": "gzip, deflate, br",
		"Origin": "https://localhost:4243",
		"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36",
		"Connection": "keep-alive",
		"Authorization": "Basic dGVzdDpzZWNyZXQ=",
		"Referer": "https://localhost:4243/",
		"Host": "localhost:8443"
	},
	"response.status": 200,
	"response.bytes": 37,
	"response.time": 52,
	"response.endtime.msecs": 1537725792274,
	"response.headers": {
		"Access-Control-Allow-Headers": "origin, accept, content-type, authorization, content-length, ceptor-apikey",
		"X-XSS-Protection": "1; mode=block",
		"Date": "Sun, 23 Sep 2018 18:03:12 GMT",
		"Connection": "keep-alive",
		"X-RateLimit-Remaining": "2",
		"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
		"X-RateLimit-Limit": "5",
		"Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE",
		"X-RateLimit-Reset": "1537725840",
		"X-Frame-Options": "sameorigin",
		"Via": "1.1 gateway1 (Ceptor/6.0.3)",
		"Access-Control-Allow-Origin": "https://localhost:4243",
		"X-Content-Type-Options": "nosniff",
		"Content-Type": "application/json",
		"Content-Length": "37",
		"X-RateLimit-Timeunit": "minute",
		"Access-Control-Max-Age": "120"
	},
	"response.body": "{\"text\":\"How nice of you to call me\"}"
}


Record response body for API Usage plugins

If checked, responses will be recorded as they are streamed back, and are available for API Usage plugins for logging.

Default value: false
JSON Key: record.responses

Remote spec reload interval

Defines the number of seconds between reloading remote OpenAPI Specs from backend servers.

Default value: 1800
JSON Key: api.remoteloadinterval.seconds

ElasticSearch Settings

When using elasticsearch to store the statistics within, you need to configure the URL and any eventual userid/password that should be used when saving statistics within it.

Note that elasticsearch can be relatively slow in some environments, so Ceptor updates it asynchronously and can queue up to 10000 requests per gateway. If your API request load exceeds elasticssearch's ability to store events fast enough, you can choose either to discard them (for optimal performance) - or to switch to synchronously storing them. If discarding events is not allowed, Ceptor will instead of sending them asynchronously switch to doing it synchronously.

Note that you will usually need very heavy sustained load of tens of thousands of API calls per second on your system for this to become a problem.

This will block Ceptor API Gateway's threads for some additional milliseconds until elasticsearch responds, and will cause delay in responding to API calls, but it will also ensure that events are not lost even if your elasticsearch cluster is not fast enough to sustain the rate of calls.

Environments & Locations

As you can see above, you configure a Location, and serve APIs from it - there is nothing the prevents you from serving API calls to the same environment from multiple locations, so you can indeed create as many locations as you wish distributed over as many gateway clusters you need and serve the same APIs in the same locations over these.

Adding Additional Security

You can use the full capabilities of the Ceptor Gateway to secure your API calls - any authentication settings you configure in your API security per API version can be overwritten within a Location by creating other authentication settings and override it. If settings for your Location authenticates a user, when the API is called the API Gateway will detect that the user is already authenticated, so it will not attempt to re-authenticate him again.

This allows you to add all sort of exotic requirements, e.g. protect your all your API calls for a particular Location / Environment by Kerberos authentication, allowing you full flexibility to either specify security authentication/authorization restrictions centrally for an environment or for each API.

If you need the OpenAPI API specification to reflect the configured security settings, e.g. OAuth2 URLs, you should configured security on the API Version level.