Request your API using Angular SDK

Introduction

As an example, we want to create a sample app using AngularJS and Restlet Cloud.

For this purpose, create an API using Restlet Cloud Quickstart wizard.

Use the Quickstart wizard

For this example, we call our API quick_start_wizard_angularjs_sdk. As it is based on the quickstart wizard, the resources associated are:
* Company
* Contact

API created via the Quickstart wizard

Download the AngularJS SDK from the Downloads tab.

Download JavaScript SDK

Archive structure

The downloaded archive has the following folder structure:

  • Quick_start_wizard_angularjs_sdkModule.js contains the SDK generated by Restlet Cloud and does not require any modification.
  • app.js is a skeleton generated by Restlet Cloud. This is the file where the custom code can be written.
  • index.html is the entry point of the application. It automatically imports the two previous files.

Usage

An HTTP server is required to be able to use the provided code. It can be served from any server.

If the OS has python installed, a SimpleHTTPServer inside the folder will do the trick:

cd /path/to/your/unzipped/sdk
python -mSimpleHTTPServer 1234

Then go to http://localhost:1234/.

Or use node http-server with the following command line:

npm install -g http-server
http-server /path/to/your/unzipped/sdk

Open http://localhost:8080/.

The developed application is now available.

Developing an app

SDK methods

By default the SDK module is named after the name of the API. In our example for an API named quick_start_wizard_angularjs_sdk the SDK is named Quick_start_wizard_angularjs_sdkClientResource. The name of the API is capitalized and appended with ClientResource.

The SDK exposes all the methods required to interact with the hosted API. For each resource there is one method per HTTP verb available.

As the Quickstart wizard generates a /companies resource accessible through GET (fetch all the companies) and POST (create a new company), the SDK will generate the following methods:

  • getCompanyList
  • postCompanyList

Note: When the resource is a plural then the SDK replaces the plural form by a singular one appended with List.

With the same convention the quickstart wizard generates a /companies/{companyId} resource accessible through GET (get the company information), PUT (update a company record) and DELETE (remove the specified company), so the methods generated are:

  • getCompany
  • putCompany
  • deleteCompany

For any method generated the parameters are provided as a JS object provided as first parameter of the method. For instance to access the company of id 1:

quick_start_wizard_angularjs_sdkClientResource.getCompany({
  companyid: 1
});

Security

By default all the resources hosted on Restlet Cloud are secured and hence require authentication. The standard configuration is based on basic authentication.

The app.js file can be filled to use authentication with the API's credentials.

Warning: Make sure you do not leave your credentials when the application goes live since anyone using the application could access them.

The resources' security should be adapted to fit the need. For instance, getting the list of companies might be authorized to Anyone.

Query for companies

Knowing this, getting the companies is pretty straight-forward and is made by calling the getCompanyList method and hooking onto the returned promise.

A special attention has to be dedicated to the .then part in the following snippets for any JS developer not familiar with promises. Since Angular is based on the Promise theory and the Q specification, it is recommended to have a good understanding of that and how it works. The AngularJS related documentation can be found there.

quick_start_wizard_angularjs_sdkClientResource.getCompanyList()
  .then(function(companies) {
    $scope.companies = companies;
  });

Note: The promises returned by the SDK are resolved directly with the body of the HTTP response.

Query for one specific company

To get a given company, the companyid must be provided as shown below:

quick_start_wizard_angularjs_sdkClientResource.getCompany({
  companyid: 1
})
  .then(function(company) {
      $scope.company = company;
  });

Update an existing company

An update is a call to putCompany with:
* the companyid which is the id of the company to update
* the body which is the new company as JSON

The promise is then resolved with the updated company.

quick_start_wizard_angularjs_sdkClientResource.putCompany({
  companyid: company.id,
  body: company
})
  .then(function(company) {
    console.log(company);
    alert('Company updated successfully');
  });

Add a new company

Adding a new company is made through the use of the post on the resource list. In our example: postCompanyList.

The only parameter to provide is the body (the JSON representation of the company).

quick_start_wizard_angularjs_sdkClientResource.postCompanyList({
  body: {
    "tags": [],
    "name": "Testing company",
    "address": {
      "street":"321312 somewhere in the street",
      "zipcode": 44000,
      "city":"Babylone"
    }
  }
}).then(function(newCompany) {
  $scope.company = newCompany;
});

Delete an existing company

Deleting a company is very similar to getting an existing company and only requires the companyid to detect which record should be deleted.

quick_start_wizard_angularjs_sdkClientResource.deleteCompany({
  companyid: 1
})
  .then(function(company) {
      $scope.company = company;
  });

Put it all together

Now let's create a sample application which is going to get the companies and let us update their name and address.

The first part is to create a simple HTML template, so let's open the provided index.html and replace the content of <div class="container"> ... </div> with the following:

<h2>Companies</h2>
<div class="row">
  <div class="col-md-6">
    <table class="table table-striped col-md-6">
      <tr>
        <th>Name</th>
      </tr>
      <tr ng-repeat="company in companies" ng-click="selectCompany(company.id)">
        <td>
          {{company.name}}
        </td>
      </tr>
    </table>
  </div>

  <div class="col-md-6" ng-if="company">
    <form>
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" placeholder="Name" ng-model="company.name">
      </div>
      <div class="form-group">
        <label for="street">Street</label>
        <input type="text" class="form-control" id="street" placeholder="Street" ng-model="company.address.street">
      </div>
      <div class="form-group">
        <label for="zipcode">ZIP code</label>
        <input type="text" class="form-control" id="zipcode" placeholder="Zip code" ng-model="company.address.zipcode">
      </div>
      <div class="form-group">
        <label for="city">City</label>
        <input type="text" class="form-control" id="city" placeholder="City" ng-model="company.address.city">
      </div>
      <button type="submit" class="btn btn-default" ng-click="save(company)">Save</button>
    </form>
  </div>
</div>

So let's break it apart to clarify it.

The company array

<div class="col-md-6">
  <table class="table table-striped col-md-6">
    <tr>
      <th>Name</th>
    </tr>
    <tr ng-repeat="company in companies" ng-click="selectCompany(company.id)">
      <td>
        {{company.name}}
      </td>
    </tr>
  </table>
</div>

In this part, a table is created with a row per company. To do so Angular iterates over the companies' array stored in the scope using the ng-repeat="company in companies".

It can also be noticed that a click on any tr is going to selectCompany which leads us to the company detail.

Company detail

The company detail is a standard form displayed if and only if a company has been selected.

It also contains various bindings to handle update of: * The name of the company * The address of the company divided into street, zip code and city

Finally the save button triggers an update of the company with the last values changed by the user.

<div class="col-md-6" ng-if="company">
  <form>
    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" placeholder="Name" ng-model="company.name">
    </div>
    <div class="form-group">
      <label for="street">Street</label>
      <input type="text" class="form-control" id="street" placeholder="Street" ng-model="company.address.street">
    </div>
    <div class="form-group">
      <label for="zipcode">ZIP code</label>
      <input type="text" class="form-control" id="zipcode" placeholder="Zip code" ng-model="company.address.zipcode">
    </div>
    <div class="form-group">
      <label for="city">City</label>
      <input type="text" class="form-control" id="city" placeholder="City" ng-model="company.address.city">
    </div>
    <button type="submit" class="btn btn-default" ng-click="save(company)">Save</button>
  </form>
</div>

At that point, the structure of the controller starts to appear. Many properties have to be set onto the $scope: * companies the list of companies * company the currently selected company * selectCompany a method which selects and recovers the company of a given id from the server * save saves a company

JavaScript part

Authentication

First let's add the credentials into the run block which are required to be able to access the API if the default security has not been changed.

.run(function ($http) {

    // Adds HTTP basic authentication to all your calls to the API
  var encoded = btoa('9ac12010-68fd-4a68-b114-127672bdd2cd:4f8bd084-6644-45f2-b4b8-b8980782093d');
  $http.defaults.headers.common.Authorization = 'Basic ' + encoded;

})

Controller

Now the last task is to add the logic into the controller which means to: * recover the companies (getCompanies) * select a company (selectCompany) * update a company (save)

.controller('MainCtrl', function ($scope, $http, $q, $location, $timeout, $window, Quick_start_wizard_angularjs_sdkClientResource) {

  var quick_start_wizard_angularjs_sdkClientResource = new Quick_start_wizard_angularjs_sdkClientResource();

  // Let's get the company
  getCompanies();

  /**
   * Recovers the information about a specific company and set it to the `company`
   * property of the scope.
   * @param {String} companyId the id of the company to load from Restlet Cloud
   * @returns {undefined}
   */
  $scope.selectCompany = function(companyId) {
    quick_start_wizard_angularjs_sdkClientResource.getCompany({
      companyid: companyId
    }).then(function(company) {
      $scope.company = company;
    });
  };

  /**
   * Updates the provided company with the new value provided.
   * The company to update is determined based on the id of the provided company.
   * @param {Object} company the new company state
   * @returns {undefined}
   */
  $scope.save = function(company) {
    quick_start_wizard_angularjs_sdkClientResource.putCompany({
      companyid: company.id,
      body: company
    }).then(function(company) {
      $scope.company = company;
      getCompanies();
    });
  };

  function getCompanies() {
    quick_start_wizard_angularjs_sdkClientResource.getCompanyList().then(function(companies) {
      $scope.companies = companies;
    });
  }

});

Congratulations on completing this tutorial! If you have questions or suggestions, feel free to contact the Help Desk.