Sei sulla pagina 1di 11

How to build a REST Web API on a

Raspberry PI in JavaScript
May 8, 2013 by Ceeb 31 Comments

One of the most useful reasons for providing your Raspberry Pi with a REST
API is to expose its inputs and outputs to a web client (on any iPhone, laptop
or desktop PC anywhere in the world) for remote monitoring and/or control.
This is part 1 of a 2 part blog showing how to implement a REST API in
JavaScript.

Whats REST ?
In recent years, the Web has turned from a network of webservers serving
mainly static pages to web browsers

Web 1.0 How the Internet was

into a full client-server architecture, where single-page client web apps use
AJAX principles to communicate with server-side applications, increasingly
via simple but powerful RESTful APIs.

The Web as a client-server application framework

REST, AJAX and JAVASCRIPT


With REST, the idea is that, rather than using complex mechanisms such as
CORBA, RPC or SOAP to connect between clients and servers, simple HTTP
queries are used. RESTful applications use HTTP requests to POST data
(create and/or update data), GET data (make queries), and delete data on the
server. Thus, REST uses HTTP for all four CRUD
(Create/Read/Update/Delete) operations.
AJAX is a popular web development technique that makes web pages
interactive using JavaScript. In AJAX, requests are sent to the server using
XMLHttpRequest objects. The response is used by the JavaScript code to
dynamically change the current page. Each XMLHttpRequest can be viewed
as a REST service request, sent using GET. And the response is often in JSON
format.
For example, if our client application wants to get the ISBN for a book the
user knows the title of, we might send our API server an HTTP GET with the
URL :
http://www.myapiserver.com/books/ISBN/Catch-22
Using jQuery we can implement this AJAX request in our client application
simply like this:

$.getJSON("http://www.myapiserver.com/books/ISBN/Cat
ch-22", function(data) {
console.log("The ISBN for this book is "+data );
});
The HTTP reply our server sends back to the client is the raw result data
not embedded inside an HTML page, not XML-encoded, just the data you
need in a way you can immediately use a String or a JSON object you can
use directly.
With REST, a simple network connection is all you need. You can even test
the API directly, by typing the API URL into your browser. For instance, try
entering the API call http://api.exip.org/?call=ipdirectly in your browser; the
API server at api.exip.org will return the public IP address of your machine
(not the same as the private IP address issued to your PC by your Routers
DHCP service, which you will see when you run ifconfig at the command
line, or displayed in your network settings). Or try out the twitter API by
enteringhttps://api.twitter.com/1/statuses/home_timeline.json?
include_entities=true in your browser. Because you havent included a key in
your request, you will see an authentication error response in the browser
window, encoded as a JSON object, which looks something like this:
{"errors":[{"message":"Bad Authentication
data","code":215}]}
As you may have noticed in these examples, REST can easily handle more
complex requests, including multiple parameters. In most cases, youll just
use HTTP GET parameters in the URL.
For example, if we can only uniquely specify a book by both title and author,
our API might accept a request like this: http://myapiserver/books/ISBN?
title=Catch-22&author=Heller

As a convention, HTTP GET requests should be for read-only queries; they


should not change the state of the server and its data. For creation, updating,
and deleting data, use POST requests.

REST on the Raspberry Pi


Ive been using Node.JS as the backend (server-side)
framework for building single-page or client-server web apps and more
recently as a Javascript platform on my Raspberry Pi. On top of providing the
advantage of an asynchronous, event-based programming model, it means I
can code in he same language Javascript on the frontend and the backend
and on the Pi.

The Raspberry Pi as a Web Application server

To install Node.JS on your Raspberry Pi, see my earlier Blog post HOW
TO INSTALL NODE.JS ON A RASPBERRY PI
On the Raspberry Pi, we need to use the Node Package Manager npm to
download and install the other modules we will need to build our web
application. We will be using the express web application framework module
initially, and also the connect module it depends on.
On your RPi, create a new directory for your project, and download the node
modules youll need as follows :
$ mkdir myapp
$ cd myapp

$ npm init
$ npm install express --save
$ npm install connect --save
Or use the -g flag if you prefer the package to be installed globally, i.e.
in /usr/local where node is installed, rather than in./node_modules. To install
global packages, you need to use sudo to execute with superuser priviledges.
The node package manager will download and install the express framework.

Coding a RESTful API example on the


Raspberry Pi
Were now going to build an example client-server application using our
Raspberry Pi as the server.
To build this full REST example, we need to create three source files on our
Raspberry Pi: The server-side Javascript code, a simple HTML page, and
some client-side Javascript.
myapi.js our server-side Javascript code uses the Node and the Express
framework to provide simplistic Web server functionality and to expose a
RESTful API.
index.html the HTML page which the browser loads from the Raspberry Pi
and uses to render the presentation layer for our application.
myclient.js Javascript code executed in the browser when our HTML page
loads. This code implements the AJAX client functionality to call our API and
render the results directly in the HTML page.
The application architecture looks like this:

Our Example using Raspberry Pi as an App Server

MYAPI.JS: The Server(RPi)-side code


Now create a file called myapi.js on your Pi and copy the code below to build
a simple server in Javascript, which processes API requests on port 3000 with
a JSON object. (Port 3000 is the standard port most commonly used for an
express server).
First we need to let Node know we will be using the http and expresspackages,
call express to create our application server as an object, and assign it to a
variable.
var http = require('http');
var express = require('express');
var app = express();
Next we will define an array of objects the client will be able to query.

var inputs = [{ pin: '11', gpio: '17', value: 1 },


{ pin: '12', gpio: '18', value: 0 }];
Then configure Express to serve index.html and any other static pages
stored in the home directory, such as your myclient.js JavaScript source file
app.use(express['static'](__dirname ));
Next we need to define the API middleware for our server-side application.
We use expresss get function to define routes for the API calls and/or page
requests to our server.
// Express route for incoming requests for a
customer name
app.get('/inputs/:id', function(req, res) {
res.status(200).send(inputs[req.params.id]);
});
// Express route for any other unrecognised incoming
requests
app.get('*', function(req, res) {
res.status(404).send('Unrecognised API call');
});
// Express route to handle errors
app.use(function(err, req, res, next) {
if (req.xhr) {
res.status(500).send('Oops, Something went
wrong!');
} else {
next(err);
}
});
Finally, start the server application, listening on port 3000:

app.listen(3000);
console.log('App Server running at port 3000');

INDEX.HTML: the homepage


Our web page simply displays a title, and sets up an input div as a placeholder
that will be used by our client-side JavaScript code in myclient.js to display
the I/O values retrieved from our RPi.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Express API server example</title>
<script src="http://code.jquery.com/jquerylatest.js"></script>
<script src="myclient.js"></script>
</head>
<body>
<H1>My Express API server example</H1>
<div id="input"></div>
</body>
</html>

MYCLIENT.JS: the client-side code


this JavaScript code will be loaded and executed on the client machine when
the browser loads our HTML page. It makes 2 calls to our API server running
on the Raspberry Pi to retrieve and display the state of two inputs.
window.onload = function () {
var url,
i,
jqxhr;

for (i = 0; i < 2; i++) {


url = document.URL + 'inputs/' + i;
jqxhr = $.getJSON(url, function(data) {
console.log('API response received');
$('#input').append('<p>input gpio port ' +
data['gpio'] + ' on pin ' +
data['pin'] + ' has current value ' +
data['value'] + '</p>');
});
}
};

Download the Source Code


You can also download the full source code (client, server and html) for this
example from github herehttps://github.com/fatkahawai/rpi-webapp-express
Create or download the three source files into a new folder on your RPi.

Running your Raspberry Pi Web App


Server
To start up your web server on your RPi , invoke your application with node,
from the folder you have saved the source files in.
$ node myapi.js
App Server running at port 3000
$
(Making sure that you have first installed the express module using npm, as
already described above.)
Your web server is now running continuously in the background, waiting for
API calls.

Finally, using another machine on the same local network, open a web
browser and navigate to your App Server hosted on the RPi.
If your RPi has the local IP address 192.168.0.22, you would enter this in your
browser:
http://192.168.0.22:3000
This will cause the browser to load your index.html file from your RPi, which
then loads your javascript client code in myclient.js.
If youre in luck, this should appear in your browser window:

Whats Next ?

One of the most useful reasons for providing your Raspberry Pi with a
RESTful API is to expose its input and output ports to web clients for remote
monitoring and control.
So in our next exercise, we will do just this, exposing the real GPIO I/O ports
through a RESTful API, which will allow you to control your Pis inputs and
outputs from any smartphone or PC wherever you are in the world.
Next
I hope this exercise has been useful. If you have any feedback or spot any
errors or omissions, feel free to leave a note in the comments section below.

Potrebbero piacerti anche