vendredi 11 juillet 2014

snapJob Part I : Creating a simple RESTFull API that rocks! REST in peace!



Creating a RESTFul API is pretty easy in many programming languages, but we want more !
We want a RESTFul API with a user interface that will self-describes the methods options and operations, and which allows as to test the various methods we've created without having to actually build the user interface at the same time. This way, we will only focus on what the API should do, without taking care of anything else.

For those who may ask, building an API is good, because this will allow us to build any front end application we want, wherever it is a html web application, an android app, a Microsoft Windows app, or an IPhone application.

To do that, we will use the following technologies :
- node.js to host, serve, and perform logical operations on data
- swagger, a node.js npm library from Wordnik that will be used to expose the API thought Express (another npm library) and present methods in a fashionable way so we can test it.

For now, we will just create a simple rest service with only one dummy method. Later on, we will add data persistence, log management, data processing, ...e

  1. Setting up the RESTFul API

    Setting up the RESTFul API is pretty easy.

    1. First, we need to copy the files that are in the "dist" directory of the swagger-ui GitHub project  into our application folder.
    2. Then we need to customize a little bit the index.html file to replace the "title" tag, and the title in the html content of the page, but most of it, we need to replace the API url (just remove the striked text) :
      $(function () {
      
      window.swaggerUi = new SwaggerUi({
      url: "http://petstore.swagger.wordnik.com/api/api-docs",
      dom_id: "swagger-ui-container",
      supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
      onComplete: function(swaggerApi, swaggerUi){
      [...]
      
    3. I also moved the "swagger-ui.js" file in the "lib" directory, and updated one line in "index.html":
      <script src="lib/swagger-ui.js" type="text/javascript">

















  • In the root folder of our application, we now need to put a few files :
    • The package.json file, that will describe dependences of our application. :
      {
          "name": "snapJobAPI",
          "version": "0.0.1",
          "dependencies": {
              "express": "*",
              "swagger-node-express": "*",
              "minimist":"*"
          }
      }
      

      express is used to serve files, swagger-node-express to handle the RESTFul api requests, and minimist to parse application parameters.
    • The app.js file, which will be our application's main file. :
      {
      var express = require("express")
          , swagger = require("swagger-node-express")
          , path = require('path')
          , argv = require('minimist')(process.argv.slice(2))
          , test = require("./models/test")
          , models = require("./models/models")
          , app = express();
      
      
      app.use('/js', express.static(path.join(__dirname, 'js')));
      app.use('/lib', express.static(path.join(__dirname, 'lib')));
      app.use('/css', express.static(path.join(__dirname, 'css')));
      app.use('/images', express.static(path.join(__dirname, 'images')));
      
      // Set the main handler in swagger to the express app
      swagger.setAppHandler(app);
      
      // Adding models and methods to our RESTFul service
      swagger.addModels(models)
          .addGet(test.dummyTestMethod);
      
      // set api info
      swagger.setApiInfo({
          title: "snapJob API",
          description: "API to manage job applications, job offers, profiles...",
          termsOfServiceUrl: "",
          contact: "yoann.diguet@snapjob.com",
          license: "",
          licenseUrl: ""
      });
      
      app.get('/', function (req, res) {
          res.sendfile(__dirname + '/index.html');
      });
      
      // Set api-doc path
      swagger.configureSwaggerPaths('', 'api-docs', '');
      
      // Configure the API domain
      var domain = 'localhost';
      if(argv.domain !== undefined)
          domain = argv.domain;
      else
          console.log('No --domain=xxx specified, taking default hostname "localhost".')
      
      // Configure the API port
      var port = 8080;
      if(argv.port !== undefined)
          port = argv.port;
      else
          console.log('No --port=xxx specified, taking default port ' + port + '.')
      
      // Set and display the application URL
      var applicationUrl = 'http://' + domain + ':' + port;
      console.log('snapJob API running on ' + applicationUrl);
      
      swagger.configure(applicationUrl, '1.0.0');
      
      // Start the web server
      app.listen(port);
      

      express is used to serve files, swagger-node-express to handle the RESTFul api requests, and minimist to parse application parameters.
    • The models/models.js file that will describe the application data output models (if we want to return user information, for example, the "user" data structure will be described here, for example) :
      exports.models = {
          "void": {
              "id": "void",
              "properties": {
              }
          }
      }
      

    • The models/test.js file that will describe a dummy test method and it's body :
      exports.dummyTestMethod = {
          'spec': {
              description : "Test method",
              path : "/test/",
              method: "GET",
              summary : "This is a dummy test method",
              type : "void",
              nickname : "dummyTestMethod",
              produces : ["application/json"]
          },
          'action': function (req, res) {
              res.send(JSON.stringify("test is ok"));
          }
      };
      

  • Run the application
    To run the application, we need to perform the following command line commands within the application directory (on windows, the node.js command-line tool is required) :
    • npm install
      
      This will install dependencies decribed in the package.json file.
    • node app.js
      This will run the application.
  • Application outputs
    Command line output application should be something like this :
    /usr/bin/node app.js
    No --domain=xxx specified, taking default hostname "localhost".
    No --port=xxx specified, taking default port 8080.
    snapJob API running on http://localhost:8080

    And in the WebBrowser, you should see something like this :


    If you click on the "Try it out" button, you should have something like this :



  • Quick note : As you can see from the code, you can launch the application with two optional parameters :
    • The first one, --port=xxx, specifies the port on with the server should listen web requests inputs (default is 8080).
    • The second one, --hostname=xxx, specifies the host url.
    Pretty nice, huh ? That wasn't so hard after all...

    Presentation of the project can be found here.
    Source code for this application can be downloaded from here.

    Next part : snapJob Part II : Managing application logs using LogStash...

    Aucun commentaire:

    Enregistrer un commentaire