Note: Since the publication of this blog, the StrongLoop API Gateway was relaunched on August 5, 2015. Read this announcement blog to learn more about the latest version.
In case you missed it, today we announced the availability of the open source LoopBack API Gateway. The LoopBack API Gateway is open source and is the “minimum viable product” (MVP) that covers key use cases piloted with our co-development partners. In this blog we’ll show you how to get started with a sample application to test out the features of the gateway.
What’s LoopBack? It’s an open source Node.js framework for developing, managing and scaling APIs. Learn more…
What is an API gateway?
An API gateway is a component within systems architecture to externalize, secure and manage APIs. The API gateway sits as an intermediary between the many consumers of APIs – API clients and the many producers of the APIs on the backend – API servers.
The basic features
loopback-gateway
is an example application to demonstrate how to build an API gateway using LoopBack. In this tutorial, we’ll build a simplified version of API gateway using LoopBack. The gateway supports basic features listed below:
The test scenario consists of three components:
The architecture is illustrated in the diagram below.
Build the gateway application
The application is initially scaffolded using slc loopback
command. We customize server/server.js to add specific features for the gateway.
Configure and ensure HTTPS
oAuth 2.0 states that the authorization server MUST require the use of TLS with server authentication for any request sent to the authorization and token endpoints. There are two steps involved here:
var httpsRedirect = require('./middleware/https-redirect');
...
// Redirect http requests to https
var httpsPort = app.get('https-port');
app.use(httpsRedirect({httpsPort: httpsPort}));
Configure oAuth 2.0
The oAuth 2.0 integration is done using loopback-component-oauth2
.
In our case, we configure the API gateway as both an authorization server and resource server.
Set up authorization server
The oAuth authorization server exposes the authorization endpoint to allow resource owners (users) to grant permissions to authenticated client applications. It also creates the token endpoint to issue access tokens to client applications with valid grants.
var oauth2 = require('loopback-component-oauth2').oAuth2Provider(
app, {
dataSource: app.dataSources.db, // Data source for oAuth2 metadata persistence
loginPage: '/login', // The login page url
loginPath: '/login' // The login processing url
});
Set up resource server
To protect endpoints with oAuth 2.0, we set up middleware that checks incoming requests for an access token and validate it with the information persisted on the server when the token is issued.
oauth2.authenticate(['/protected', '/api', '/me'], {session: false, scope: 'demo'});
Rate Limiting
Rate limiting controls how many API calls can be made from client applications within a certain period of time.
The sample uses a token bucket based algorithm to enforce the rate limits based on authenticated client application ids.
var rateLimiting = require('./middleware/rate-limiting');
app.use(rateLimiting({limit: 100, interval: 60000}));
Proxy
The proxy middleware allows incoming requests to be forwarded/dispatched to other servers. In this tutorial, we’ll route /api/ to http://localhost:3002/api/. The implementation is based on node-http-proxy.
var proxy = require('./middleware/proxy');
var proxyOptions = require('./middleware/proxy/config.json');
app.use(proxy(proxyOptions));
{
"rules": [
"^/api/(.*)$ http://localhost:3002/api/$1 [P]"
]
}
Sign up client applications and users
oAuth 2.0 requires client applications to be registered. In this tutorial, we can simply create a new instance with the LoopBack built-in application model. The client id is 123 and the client secret is secret
. The resource owner is basically a user. We create a user named bob
with password secret
for testing.
function signupTestUserAndApp() {
// Create a dummy user and client app
app.models.User.create({username: 'bob',
password: 'secret',
email: '[email protected]'}, function(err, user) {
if (!err) {
console.log('User registered: username=%s password=%s',
user.username, 'secret');
}
// Hack to set the app id to a fixed value so that we don't have to change
// the client settings
app.models.Application.beforeSave = function(next) {
this.id = 123;
this.restApiKey = 'secret';
next();
};
app.models.Application.register(
user.id,
'demo-app',
{
publicKey: sslCert.certificate
},
function(err, demo) {
if (err) {
console.error(err);
} else {
console.log('Client application registered: id=%s key=%s',
demo.id, demo.restApiKey);
}
}
);
});
}
Run the demo
There are a few steps to run the demo application.
Create the api server
$ slc loopback demo-api-server
$ cd demo-api-server
$ slc loopback:model note
[?] Enter the model name: note
[?] Select the data-source to attach note to: db (memory)
[?] Expose note via the REST API? Yes
[?] Custom plural form (used to build REST URL):
Let's add some note properties now.
Enter an empty property name when done.
[?] Property name: title
invoke loopback:property
[?] Property type: string
[?] Required? No
Let's add another note property.
Enter an empty property name when done.
[?] Property name: content
invoke loopback:property
[?] Property type: string
[?] Required? No
Run the API server
PORT=3002 node .
Open a browser and point to http://localhost:3002/explorer. Locate the ‘POST notes’ section and add a few notes.
Run the gateway
node .
Test out https
Open a browser and point to http://localhost:3000. You will see the browser to be redirected to https://localhost:3001. Please note your browser might complain about the SSL certificate as it is self-signed. It’s safe to ignore the warning and proceed.
Test out oAuth 2.0 and proxy
The home page below shows multiple options to try out the oAuth 2.0 grant types. Let’s start with the explicit flow.
Now you need to log in as the resource owner.
The following dialog requests permission from the resource owner (user) to approve the access by the client application.
Click “Allow”. The browser will be redirected to the callback page.
The callback page builds the links with the access token. Click on ‘Calling /api/notes’.
Test out rate limiting
To test rate limiting, please run the following script which sends 150 requests to the server. The script prints out the rate limit and remaining.
node server/scripts/rate-limiting-client.js
Test out JWT
We support JSON Web Token (JWT) as client authentication and authorization grant for oAuth 2.0. See https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-10 for more details.
The first command requests an access token with a JWT token signed by the private key.
node server/scripts/jwt-client-auth.js
The second command requests an access token using a JWT token as the assertion type.
node server/scripts/jwt-client-auth.js <authorization code>
Summary
The open source LoopBack gateway provides key functionality that enables you to manually piece together middleware and specify your business rules through plain JavaScript hooks. The LoopBack API gateway serves as a reference implementation and will be limited to its current functionality. It currently fulfills the MVP use cases without components and policies.
We expect that complex enterprises need to manage API endpoints at runtime, using the dynamic controls and additional functionality of components and policies provided by the StrongLoop API Gateway. It will provide the commercial-grade features and performance required for top-tier enterprise API management.
**What’s next?
-
Ready to develop APIs in Node.js and get them connected to your data? Check out the Node.js LoopBack framework. We’ve made it easy to get started either locally or on your favorite cloud, with a simple npm install.