Tutorial: Implementing Models

Integrating Models
Integrating Protected Endpoints

For our final act of integration we will expose and protect some rudimentary endpoints.  Our small utility API provides information on IP addresses and domain names but for good reason we would much rather not expose these for public consumption as they could be misused by spammers and other ill-willed persons.

So as to keep this article brief the Swagger specifications can be found in the specs/swagger.yaml file.  Let us take a singular look at one of the endpoints namely /geo/:ip located in controllers/geo.js

// The Essentials
var maxmind = require('maxmind'); // MaxMind's GeoData
var whois = require('whois-api'); // WHOIS domain lookup
var nslookup = require('nslookup'); // NSLOOKUP-type library

// Some Configuration
var lookup = maxmind.openSync('./db/GeoLite2-City.mmdb', {
  cache: {
    max: 1000, // max items in cache
    maxAge: 1000 * 60 * 60 // life time in milliseconds
  }
});

On line 16 we include the GeoIP lookup library located at https://github.com/runk/node-maxmind

Lines 21 through 26 includes code to instantiate and open the database located in db/GeoLite2-City.mmdb for use throughout the rest of the controller.

  /** This protected endpoint makes use of a database to determine the country and city of an IP */
  app.get('/geo/:ip', function(req, res, next) { passport.authenticate('jwt',
    function(err, user, info) {
       if (!user) {
          return res.send(401, {error:{code: 401, status: 'ACCESSDENIED', message: 'Access denied'}});
       } else {
          // Ensure that this is a valid IP address
          if (req.params.ip.match(/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/)) {
             return res.send(200, {success:{code: 200, status: 'SUCCESS', message: 'Success'}, results:lookup.get(req.params.ip)});
          } else {
             return res.send(401, {error:{code: 406, status: 'BADREQUEST', message: 'Invalid IP address'}});
          }
       }

    })(req,res,next);
 });

Above between lines 52 and 67 we define the /geo/:ip route.  Recall that ‘:ip’ is a special-purpose parameter which maps to req.params.ip for use in the controller.  Using this parameter we first make use of a regular expression on line 59 to ensure that the supplied input conforms somewhat to the syntax of an IP address and if successful we perform a lookup on the GeoIP database.  The results of this lookup are returned to the caller as a JSON-formatted response.

Note that on line 53 we protect the endpoint by requiring the ‘jwt’ PassportJS strategy requiring the caller to supply a valid JWT token when invoking the endpoint.

Feel free to explore the remaining endpoints!

In future articles we will build upon this example and increase our knowledge and confidence in designing and developing APIs.

Was This Helpful?
All of the content on this site is presented without advertiser support and is produced exclusively by me. If you find any of this information useful please consider it against the cost of a course or book.

I gladly accept donations of any amount which goes directly towards producing more quality content and videos for this site.

[wpedon id=119]

 

Pages: 1 2 3 4 5

Written by YourAPIExpert