Understanding REST and APIs

Cybersecurity First Principles in this lesson

Introduction

In this module, you will learn what a RESTful API is, how Littlebits uses APIs to monitor and issue commands to the cloudbit, and how you can use the Littlebits API yourself.

Goals

By the end of this tutorial, you will be able to:

Materials Required

For this lesson, you will need:

Prerequisite lessons

You should complete the Intro to components using Littlebits Droids and Web services and IoT using Littlebits and IFTTT lessons before attempting this lesson.

Table of Contents

Step 1: Background

Before we get started, lets talk about what an API is.

This background text and its associated images are modified for this setting by Matt Hale. Modifications are licensed under creative commons share-alike. The original material it is based upon was created by the Mozilla foundation and its contributors. Credit: https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages

HTTP is a protocol which allows the fetching of resources, such as HTML documents. It is the foundation of any data exchange on the Web and a client-server protocol, which means requests are initiated by the recipient, usually the Web browser. A complete document is reconstructed from the different sub-documents fetched, for instance text, layout description, images, videos, scripts, and more.

A Web document is the composition of different resources

Clients and servers communicate by exchanging individual messages (as opposed to a stream of data). The messages sent by the client, usually a Web browser, are called requests and the messages sent by the server as an answer are called responses.

HTTP as an application layer protocol, on top of TCP (transport layer) and IP (network layer) and below the presentation layer.Designed in the early 1990s, HTTP is an extensible protocol which has evolved over time. It is an application layer protocol that is sent over TCP, or over a TLS-encrypted TCP connection, though any reliable transport protocol could theoretically be used. Due to its extensibility, it is used to not only fetch hypertext documents, but also images and videos or to post content to servers, like with HTML form results. HTTP can also be used to fetch parts of documents to update Web pages on demand.

HTTP Messages

HTTP messages are composed of textual information encoded in ASCII, and span over multiple lines. In HTTP/1.1, and earlier versions of the protocol, these messages were openly sent across the connection. In HTTP/2, the once human-readable message is now divided up into HTTP frames, providing optimization and performance improvements.

Web developers, or webmasters, rarely craft these textual HTTP messages themselves: software, a Web browser, proxy, or Web server, perform this action. They provide HTTP messages through config files (for proxies or servers), APIs (for browsers), or other interfaces.

From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.

The HTTP/2 binary framing mechanism has been designed to not require any alteration of the APIs or config files applied: it is broadly transparent to the user.

HTTP requests, and responses, share similar structure and are composed of:

  1. A start-line describing the requests to be implemented, or its status of whether successful or a failure. This start-line is always a single line.
  2. An optional set of HTTP headers specifying the request, or describing the body included in the message.
  3. A blank line indicating all meta-information for the request have been sent.
  4. An optional body containing data associated with the request (like content of an HTML form), or the document associated with a response. The presence of the body and its size is specified by the start-line and HTTP headers.

The start-line and HTTP headers of the HTTP message are collectively known as the head of the requests, whereas its payload is known as the body.

Requests and responses share a common structure in HTTP

HTTP Requests

Start line

HTTP requests are messages sent by the client to initiate an action on the server. Their start-line contain three elements:

  1. An HTTP Method, a verb (like GET, PUT, POST, or DELETE) or a noun (like HEAD or OPTIONS), that describes the action to be performed. For example, GET indicates that a resource should be fetched or POST means that data is pushed to the server (creating or modifying a resource, or generating a temporary document to send back). PUT modifies an existing resource, while DELETE removes one.
  2. The request target, usually a URL, or the absolute path of the protocol, port, and domain are usually characterized by the request context. The format of this request target varies between different HTTP methods. It can be
    • An absolute path, ultimately followed by a '?' and query string. This is the most common form, known as the origin form, and is used with GET, POST, HEAD, and OPTIONS methods.
      POST / HTTP 1.1 GET /background.png HTTP/1.0 HEAD /test.html?query=alibaba HTTP/1.1 OPTIONS /anypage.html HTTP/1.0
    • A complete URL, known as the absolute form, is mostly used with GET when connected to a proxy.
      GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
    • The authority component of a URL, consisting of the domain name and optionally the port (prefixed by a ':'), is called the authority form. It is only used with CONNECT when setting up an HTTP tunnel.
      CONNECT developer.mozilla.org:80 HTTP/1.1
    • The asterisk form, a simple asterisk ('*') is used with OPTIONS, representing the server as a whole.
      OPTIONS * HTTP/1.1
  3. The HTTP version which defines the structure of the remaining message, acting as an indicator of the expected version to use for the response.

Headers

HTTP headers from a request follow the same basic structure of an HTTP header: a case-insensitive string followed by a colon (':') and a value whose structure depends upon the header. The whole header, including the value, consist of one single line, which can be quite long.

There are numerous request headers available. They can be divided in several groups:

Example of headers in an HTTP request

Body

The final part of the request is its body. Not all requests have one: requests fetching resources, like GET, HEAD, DELETE, or OPTIONS, usually don’t need one. Some requests send data to the server in order to update it: as often the case with POST requests (containing HTML form data).

Bodies can be broadly divided into two categories:

HTTP Responses

Status line

The start line of an HTTP response, called the status line, contains the following information:

  1. The protocol version, usually HTTP/1.1.
  2. A status code, indicating success or failure of the request. Common status codes are 200 (ok), 404 (Not found), or 500 (Server error)
  3. A status text. A brief, purely informational, textual description of the status code to help a human understand the HTTP message.

A typical status line looks like: HTTP/1.1 404 Not Found.

Headers

HTTP headers for responses follow the same structure as any other header: a case-insensitive string followed by a colon (':') and a value whose structure depends upon the type of the header. The whole header, including its value, presents as a single line.

Example of headers in an HTTP response

Body

The last part of a response is the body. Not all responses have one: responses with a status code, like 201 or 204, usually don’t.

Bodies can be broadly divided into three categories:

Step 2: Ok, lets take a look at a real API

Phew, enough background. In the previous lesson, we wired our cloudbit up to the web and explored how we could send it signals using IFTTT. We saw that if our cloudbit detected an input signal (a request), we could have IFTTT do something (send a response). These concepts, i.e. request and response, are central to the concept of RESTful APIs. REST, or REpresentational State Transfer, APIs, or Application Programming Interfaces, are tools that developers use to provide abstraction and resource encapsulation to people who want to interact with their data.

APIs allow you to get and save data back to the application, without needing to tightly integrate with that application. This improves simplicity and helps your code to be more modular. APIs include endpoints, such as /api/events, that allow you to access certain specific data (e.g. events in this example). API endpoints help provide minimization since users can only interact with the application through those interfaces provided by the developer.

…Enough talk! Lets look at an API!

Open Chrome and go to http://developers.littlebitscloud.cc/. You are looking at the cloudbit API. This is what IFTTT uses to handle requests and responses.

You can see that Littlebits tells us all about how to interact with our cloudbit using the API. Lets try it out.

Step 3: Getting our API Key

Secure APIs don’t just accept requests and provide responses to anyone. APIs use a concept called least privilege to allow end-users to only have access to the features they need. Since we own the cloudbit, we should have the ability to do anything we want with it, but we might want to prevent other people from abusing and misusing our cloudbit.

To ensure that only we can program our cloudbit, Littlebits provides something called an API Key. This key is a really long alphanumerical string that would be hard to crack. Lets find our key, so we can issue commands to our cloudbit.

Go to http://control.littlebitscloud.cc/

Login using the account you used in the previous lesson

Once logged in, click on your cloudbit:

Now go to the settings menu. You should see your access token API Key, you will need this string in next steps - so keep it handy. In practice, you wouldn’t want to share this with anyone.

Step 4: Making your first REST request

Now that we have our API Key, lets use it to make a request.

POSTMAN is a REST client, that allows end users to make requests to test their APIs. Lets use it to test the cloudbit API. Launch POSTMAN by typing chrome://apps into the Chrome address bar, hit enter, and then click the POSTMAN icon.

Loading Postman

In POSTMAN, lets build a new GET request targeted at the URL https://api-http.littlebitscloud.cc/v2/devices

Authorization: Bearer <your access token with no angled brackets>

You can add the header as a key value pair, where the key is Authorization and the value is Bearer <insert your access token here, remove the angled brackets>. Make sure to use your access token.

If all goes well you should see something like:

GET request

[
    {
        "label": "mlhale-cloudbit",
        "id": "00e04c036f15",
        "subscriptions": [],
        "subscribers": [],
        "user_id": 175306,
        "is_connected": true,
        "input_interval_ms": 200
    }
]

This tells me the label of my cloudbit is mlhale-cloudbit and that it currently doesn’t have any subscribers or subscriptions.

Step 5: GET device info

Now that we know our device id, we can use it to make a specific request for our device.

https://api-http.littlebitscloud.cc/v2/devices/<your-device-id>

You should get the same device info back, but notice that it is now not in square brackets - this means it is a singleton instead of a list.

GET request.

Step 6: First POST request to turn the device on

Now that we have the basics of GET requests to access device info, lets try issuing a POST request to actually make our device do something.

Littlebits Setup

https://api-http.littlebitscloud.cc/v2/devices/<your-device-id>/output

Before you issue the request make sure the headers are set as follows:

Headers:

Authorization: Bearer <your access token>
Content-type: application/json

POST request

Now click on the Body tab (next to the Headers tab). Select the Raw input option and type the JSON shown below to tell cloudbit to turn the LED on at 100% brightness and to stay on for 5 seconds.

Body:

{
    "percent": 100,
    "duration_ms": 5000
}

POST request

Now send the request You should get back:

{
    "success": true
}

and you should see your LED light up. You just used REST!

Checkpoint

Lets review what we’ve learned.

https://www.qzzr.com/c/quiz/429280/8f69a8f7-0a69-4efa-9c3e-2aa38944ed1d

Step 7: Adding a subscriber to handle incoming events.

Lets add a subscriber to catch input events going to the cloudbit:

same headers as before body:

{
    "publisher_id": "<your device id>",
    "subscriber_id": "http://ourserver.com/endpoint"
}

But where is our server? We don’t have one yet. We will talk about deploying a server in the next lesson and then come back to this.

Additional Resources

For more information, investigate the following.

Lead Author

Acknowledgements

Special thanks to Dr. Robin Gandhi, Andrew Li, and April Guerin for reviewing and editing this module.

License

Nebraska GenCyber Creative Commons License
is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Overall content: Copyright (C) 2017-2018 Dr. Matthew L. Hale, Dr. Robin Gandhi, Dr. Briana B. Morrison, and Doug Rausch.

Lesson content: Copyright (C) Dr. Matthew Hale 2017-2018.
Creative Commons License
This lesson is licensed by the author under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.