Chapter 2. Working with web APIs

This chapter covers

  • Structure of a simple API
  • Ways to inspect calls to an API
  • Interaction between an API and a client application
  • Deployment of the sample API and application on your system

The next few chapters cover the server-client interaction in detail, but this chapter helps you understand the concepts with a simple example of an API and sample application. Most basic API examples use a to-do list, but that’s kind of overused. I decided to go a different way: I’ve selected a list application with pizza toppings. Note that this particular application is simple by design; the goal is to show you how to interact with the API, and how an application interacts with an API. If this were a production application it would have a full pizza, or pizzas, and the database wouldn’t be shared, but for the goals here I’ve taken out as much complexity as possible to make the basic principles clear.

Looking at an API is interesting, but it doesn’t necessarily help you to understand how it can drive an application. Additionally, performing actions such as create and delete in a browser is challenging, so in addition to the API I’ve included a simple application using this API with JavaScript. This application exercises all the functionality in the API so you can see how an application interacts with a web API.

To get an idea of how this works in practice, I’ve created a basic API using Node.js, a JavaScript-based web server framework. (You can learn more about this framework at www.nodejs.org.) The API supports all the needed actions to represent a complete system: create, read, update, and delete. The first task will be to explore the API in a browser using the read functionality.

This application runs on a web host at www.irresistibleapis.com/demo. You can check out the application there and follow along with the concepts in this chapter. If you’re a developer and want to explore the code more intimately, use the exercises at the end of the chapter to get the example running on your own system, including both the Node.js application and the HTML/JavaScript web application. Section 2.6 also describes the various moving parts to this API and application so you can play with it as you like.

2.1. HTTP basics

To understand the transactions between the client and the server in API interactions, you’ll need a basic grasp of how HTTP works. Chapter 4 covers this topic in more detail, but for now I’ll give you some high-level information about the protocol.

You’re probably most familiar with HTTP as the way web browsers get information from web servers. An HTTP transaction is composed of a request from the client to the server (like a browser asking for a web page), and a response from the server back to the client (the web page from the server, for a browser). First, I’ll describe the elements in an HTTP request. You’re familiar with the URL, the address that you type into the address box on a browser, but that address is only one portion of the information sent from your browser to the server in order to process a web request.

2.1.1. HTTP request

Figure 2.1 illustrates the elements that make up an HTTP request, along with examples of how these sections are used. The HTTP request is usually sent with headers, setting the context for the transaction. An HTTP request always has a method; methods are the verbs of the HTTP protocol. To understand what your browser does, imagine that you’re visiting my main website. Here are the pieces of the request that are sent by your browser:

  • Headers: Accept: text/html— This tells the server that the browser wants to get an HTML-formatted page back. It’s the most readable format for humans, so it makes sense that your browser would request it.
  • Method: GET—This is the read method in HTTP and is generally the method used by browsers when reading web pages.
  • URL: http://irresistibleapis.com—This is the only piece you indicated for the browser.
  • Body: none— A GET request doesn’t need a body, because you’re not changing anything on the server—you’re reading what’s there.

Figure 2.1. An HTTP request will always have a method and will be sent to a specific URL, or resource. Depending on the specific call, headers may be sent to specify information about the request. If the call is designed to write new information to the system, a body will be sent to convey that information.

All the actions of CRUD (create, read, update, and delete) are represented by methods within HTTP:

  • Create: POST
  • Read: GET
  • Update: PUT
  • Delete: DELETE

The URL is the unique identifier for the resource. It’s like any other URL on the internet, except in this case it’s used to describe the resource in an application system. If parameters are needed for the request, such as a keyword for search, they’re included in the parameters of the request. To see how parameters would look, here’s an example search request:

http://www.example.com/api/v1.0/search?keyword=flintstone&sort=alphabetical

In this example, the resource being called is http://www.example.com/api/v1.0/search. The question mark and everything following it are parameters giving more information about what the client wants in the response. A body section is only sent for create (POST) and update (PUT) transactions.

Next, I’ll describe the sections of an HTTP response.

2.1.2. HTTP response

Figure 2.2 shows the elements of a typical HTTP server response. The server is likely to send back several headers giving information about the system and the response. All requests have a method, and all responses have a status code. These status codes are described in more detail in chapter 4, but for now it’s sufficient to know that 2XX means that the request was successful, 3XX is a redirect to another location, 4XX is an error in the request from the client, and 5XX means the server had a problem. In the earlier example, calling my website, the server would’ve responded with the following:

  • Status code: 200— Everything worked correctly.
  • Headers:

    • Content-Type: text/html—as requested by the client
    • Date: <date of response>
    • Content-Length: <size of response>
  • Body— The content of the page. This is what you see if you “view source” within the browser—the HTML page that tells the browser how to render the page and what content to display.
Figure 2.2. A response will always have a status code, and a well-designed platform will send headers to provide information about the response (such as size or the content type). For most requests, a body will be sent back from the server to provide information about the current status of the resource.

2.1.3. HTTP interactions

Every HTTP transaction between a client and server is composed of a request, sent from the client to the server, and a response, sent from the server back to the client. There’s no higher level interaction; each request/response is stateless and starts again from scratch. To help you understand this better, I’ll move on to a discussion of a specific API.

2.2. The Toppings API

Many different styles of API are available, but the one I’m going to be using and talking most about here is a Representational State Transfer (REST)-style API, the most common type of web API.

As discussed in chapter 1, REST APIs are designed to work with each resource as a noun. A specific resource within a system has a unique identifier, which is a URL, like the ones you visit in the browser. This URL identifies the resource in the system and is designed to be understandable when viewed. For example, with a REST API you could view the list of existing toppings with the following request:

http://irresistibleapis.com/api/v1.0/toppings

These are the actual URLs, retrieved with a GET (read) operation. If you put the preceding URL in a browser, you’ll see the results displayed in figure 2.3.

Figure 2.3. Example result of a web call in a browser. The response is JSON, a common markup language for web APIs. As you can see, the formatting makes it easy to understand the content of the response.

You can visit this URL in your browser right now and get the information about a single topping or a list of toppings. Figure 2.3 shows what this call will look like in a web browser. Go ahead and try both of these calls in your own web browser to see how easy it is to retrieve information from this kind of service. Again, this is like any other web request, only formatted for a computer to work with.

Now, to view a single topping, you’d take the id field from the list you retrieved and append it to the URL. Basically, you’re saying, “Give me the toppings list” and then, “but just the one with the ID of 1.” Almost all APIs work this way. The parent level is a list of items, and adding an ID will retrieve a single member of the list.

http://irresistibleapis.com/api/v1.0/toppings/1

The same resource is accessed to update, view, or delete a particular item, using different HTTP methods (as described in section 2.1) to tell the server what you want to do. You can add new items by sending a POST to the list itself (so in the earlier case, the /toppings endpoint would be used to add a new topping). This type of API encourages engagement and innovation by the developers, and consistency across multiple API providers makes it easier to get up and going writing clients.

2.3. Designing the API

To go through the steps, imagine an online website for a pizza parlor. Users are having trouble interfacing with the pizza ordering system and want to be able to customize their pizzas. The company wants to increase customer satisfaction. This represents the business value for this platform. Figure 2.4 illustrates each call to the system and how it would be formatted.

Figure 2.4. This diagram represents the complete set of interactions with the API system. The GET request reads the current value of the resource, whether it’s a list or an individual item. POST is only allowed at the list level, and creates a new resource in the system. PUT updates and DELETE deletes an existing resource. All four of the needed methods, Create, Read, Update, and Delete, are represented in this diagram.

To provide this, they need to create a system that consistently allows users to pick different pizza toppings and keep them in a list (use case). The company decides to measure success by determining the increase in people finishing up started orders (measurements). Fortunately for this example, it’s relatively easy to figure out how an API can meet these needs.

Because I’m creating a resource-based API, each request will be a unique URL describing one piece of the back-end structure with a method describing what the client wants to do with that resource. In this case, I have only two different types of resources: individual toppings and lists of toppings. Individual topping resources such as /api/v1.0/toppings/1 are used for viewing, editing, and deleting a single topping. The list resource /api/v1.0/toppings is used for viewing all toppings or for adding a new topping to the list. Table 2.1 shows each call to the API and a description of what it does.

Table 2.1. API calls

API call

Description

GET /api/v1.0/toppings List current toppings
GET /api/v1.0/toppings/1 View a single topping
POST /api/v1.0/toppings Create a new topping
PUT /api/v1.0/toppings/1 Update an existing topping
DELETE /api/v1.0/toppings/1 Delete an existing topping

And that’s it. The platform features create, read, update, and delete operations available to you by combining the HTTP methods with the URLs for your resources. But what do you get when you make these calls? When you GET the resource for a single topping, you get information about that topping. Try this now in your browser: http://irresistibleapis.com/api/v1.0/toppings/1.

Listing 2.1. Retrieving a single topping

This response is represented in JavaScript Object Notation (JSON), a formatting syntax first described in chapter 1. JSON is covered in more detail in chapter 4, but for now you can see how the data is structured. (If you want more information about JSON, you can find it at http://json.org.) The curly braces indicate an object, which is a group of pairings of names and values. What’s represented here is a JSON structure describing a single object—a “topping,” which has an ID of 1 and a title of Pepperoni. This is the same resource address a client can access to view, delete, or update an existing topping. This means that the URL for the single topping is the toppings list of http://irresistibleapis.com/api/v1.0/toppings followed by the ID of the topping from within this structure—so it’s http://irresistibleapis.com/api/v1.0/toppings/1.

If you GET the resource for the list of toppings directly, the returned information includes a list instead of a single object. Call this URL in your browser to see the list: http://irresistibleapis.com/api/v1.0/toppings.

Listing 2.2. Retrieving a list of all toppings

In this case, because the request was for a list of objects, square brackets demonstrate that the returned object contains a list of toppings. Each individual topping looks the same as listing 2.1. Again, this is how information is represented in JSON. To understand these calls and responses, remember that an object (with keys and values) is represented by curly braces, and a list (an unnamed collection of items) is represented with square brackets. In some programming languages these are referred to as hashes and arrays.

Both of these calls can be made from a standard web browser. If other people have added items to the list, you’ll see those included in the list view as well; this is a live call into the API system and returns the appropriate information. In this case, the API is generated by node. If you’re a developer who’s interested in learning more about the back end of the system, Exercise 3 at the end of the chapter will give you information about how to run this system on your own, as well as the application running on top of the API.

This simple API interaction gives you the opportunity to start understanding some of the topics covered in chapter 4.

2.4. Using a web API

You can interact with this API in various ways, as you’ll learn in this section. Feel free to try any or all of these approaches to see how the interaction works.

2.4.1. Browser

A browser can make GET calls to specific resources easily. Note that this is easy in the case of my demo API because there’s no authentication to worry about. The challenge is that the browser doesn’t have any way to easily update, delete, or create new items. Using the developer tools or web inspector in your browser can give you more information about the call as well.

For instance, the Chrome web browser has developer tools that allow you to inspect the traffic it’s processing. Figure 2.5 shows what these tools look like in the browser. I’ll break down what you’re seeing here in terms of what I described earlier. Note that the Chrome tools are showing the request and response combined together in the tab.

Figure 2.5. The Chrome browser makes it possible to see information about the request and response headers, the body of the request or response, and other useful information about the transaction. Although browsers aren’t designed to send PUT or DELETE responses, the information provided here can go a long way in helping you to understand the interactions with the platform.

For the request:

  • HeadersAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp;*/*;q=0.8—This is the list of accepted formats for this browser request, in order of preference. Because it includes */* (meaning “any content type”) late in the list, the browser will accept any type of response and do the best it can with it. Many other headers are shown in figure 2.5. Take a look at them and run the same request on your system to see how they change and what stays the same in each request/response transaction.
  • MethodGET
  • URLhttp://irresistibleapis.com/api/v1.0/toppings
  • Request body—none
  • Status code—200 OK

2.4.2. Command line (curl)

If you’re comfortable with the command line, you can use the curl command to make calls to the API as well. This tool is fairly straightforward and makes it possible to interact with the API more completely, using all the available methods rather than limiting transactions to read operations as the browser does. curl is native on UNIX-based systems such as Linux and Macintosh, and you can install it easily for Windows from http://curl.haxx.se/download.html.

Let’s take a quick tour through the API using curl. By default, curl uses GET (read), but you can specify other methods on the command line, as shown in the following examples. Remember that your responses may be different if other people have been changing things; go ahead and work with what you get. Don’t be shy—this API is for this book, and you can’t break anything important. The best way to understand this type of system is to work with it yourself.

First, let’s use curl to look at a single topping. Lines beginning with a dollar sign indicate a command-line call. The other information is the information returned by the server itself.

Listing 2.3. GET /api/v1.0/toppings/1
$ curl http://irresistibleapis.com/api/v1.0/toppings/1
{
  "topping": {
    "id": 1,
    "title": "Pepperoni"
  }
}

That seems pretty reasonable. I’d eat a pizza with pepperoni on it. Let’s list all the toppings and see what else is on the pizza. Remember that the list for the toppings is at the parent level, or /api/v1.0/toppings.

Listing 2.4. GET /api/v1.0/toppings
$ curl http://irresistibleapis.com/api/v1.0/toppings
{
  "toppings": [
    {
      "id": 1,
      "title": "Pepperoni"
    },
    {
      "id": 2,
      "title": "Pineapple"
    },
    {
      "id": 3,
      "title": "Pickles"
    }
  ]
}

Wait, what? Pickles? That’s kind of gross. Let’s delete that one. The id for it is 3, so the correct path to operate on is /api/v1.0/toppings/3.

Listing 2.5. DELETE /api/v1.0/toppings/3
curl -i -X DELETE http://irresistibleapis.com/api/v1.0/toppings/3
{
  "result": true
}

The response here says we succeeded. To be sure, let’s pull a list of toppings again.

Listing 2.6. GET /api/v1.0/toppings
$ curl http://irresistibleapis.com/api/v1.0/toppings
{
  "toppings": [
    {
      "id": 1,
      "title": "Pepperoni"
    },
    {
      "id": 2,
      "title": "Pineapple"
    }
  ]
}

Okay, that’s much better. But our pizza has pepperoni and pineapple, and I’d much prefer ham with my pineapple. Let’s go ahead and change that first one to make the pizza how I want it. To update an existing item, the command needs to send a PUT to the resource with the new information required.

Listing 2.7. PUT /api/v1.0/toppings/1
$ curl -i -H "Content-Type: application/json" -X PUT -d '{"title":"Ham"}'
http://irresistibleapis.com/api/v1.0/toppings/1
{
  "topping": {
    "id": 1,
    "title": "Ham"
  }
}

Nice, now the pizza is looking pretty good. But as far as I’m concerned the pizza is merely a vehicle to get cheese in my mouth, so I’ll add some extra cheese to go with the Hawaiian pizza I’ve built.

Listing 2.8. POST /api/v1.0/toppings/1
$ curl -H "Content-Type: application/json" -X POST -d '{"title":"Extra extra
 cheese"}' http://irresistibleapis.com/api/v1.0/toppings
{
  "topping": {
    "id": 3,
    "title": "Extra extra cheese"
  }
}

Let’s do one final check to make sure that the pizza looks good.

Listing 2.9. GET /api/v1.0/toppings
$ curl http://irresistibleapis.com/api/v1.0/toppings
{
  "toppings": [
    {
      "id": 1,
      "title": "Ham"
    },
    {
      "id": 2,
      "title": "Pineapple"
    },
    {
      "id": 3,
      "title": "Extra extra cheese"
    }
  ]
}

Awesome! Now the pizza is just right.

Note that with curl you can also pass -i for slightly more chatty information, or –v for a much larger dose of verbose output. If you’re having fun and you’d like to try those now, feel free. The extra details you’ll see are HTTP transaction details, which are described in chapter 4.

2.4.3. HTTP sniffers

Browsers have become good at showing information about the calls they’re making, but this is of limited use for a couple of reasons. As I mentioned earlier, a browser is only capable of sending a read request, which restricts the actions you’re able to explore. When you submit a form, it creates a create (POST) request, but you can’t arbitrarily call these operations in your browser.

HTTP sniffers are tools that allow you to explore all the HTTP traffic your system processes. HTTP sniffers watch and report on the network traffic your system is generating, whether it comes from a browser, an application, or a raw command-line call. With these tools, you can see the entirety of the HTTP request and response, and this allows you to debug what’s happening if you’re running into issues.

If you’re using a Mac, HTTPScoop (www.tuffcode.com) is a friendly choice. It’s easy to set up and use, and the output is clear and complete. The downside to this tool is that it can’t monitor secure transactions (HTTPS calls), and so it’s not going to work with any API requiring secure calls. For the purposes of this book, though, you’ll only be accessing a nonsecure API (the demo API), so HTTPScoop is a fine choice—it would be my first choice for any Mac users wanting a reasonably intuitive experience. The license cost is $15, but you can try it for two weeks for free.

Figure 2.6 shows an example of the windows in HTTPScoop. For this chapter, I’ll focus on the main screen listing all calls and the Request/Response tab. Later in the book you’ll learn about headers, status codes, and other HTTP details so you can understand how they all interact together. For now, though, consider the request to be a simple request and response, and don’t worry about particular details if you’re not already familiar with HTTP.

Figure 2.6. This is an example of a call being inspected by HTTPScoop. On this basic landing page, you can see the Request URL, representing the resource. The content type of the response, status code, and response size are also provided.

For Windows users, the best choice out there is Fiddler, which you can find at www.telerik.com/fiddler. For Windows, Mac, and Linux, there’s a slightly more complicated choice in Charles (www.charlesproxy.com). If you’re quite advanced in your network administration skills, you can try out Wireshark from www.wireshark.org. Wireshark is available and free for every major platform and sniffs all kinds of traffic, not only web/HTTP traffic, but the interface is complex, and it can be difficult to understand what you’re seeing.

Exercise 1

Watch the traffic in an HTTP sniffer as you go through the exercises from this chapter. Use the curl calls to access the API directly and see what the calls look like. For more verbosity with curl, you can use –v in your command and see more information about the call from the client side. Compare the information in the sniffer to what curl sends and see if you can find patterns. Which debugging method gives the best information? Which one is easier for you to use?

Exercise 2

Make a deliberately incorrect call. Call /api/v1.0/toppings/100—there’s not likely 100 toppings on the pizza, so this is a bad call. What kind of output did you get from curl –v? What did the HTTP sniffer show? The status code tells you how the system responded, which should give you the information you need to figure out what the issue is.

2.5. Interaction between the API and client

Seeing these GET calls to the API is somewhat interesting, but unfortunately you can’t see the POST, PUT, or DELETE calls using a browser. curl isn’t intuitive for exploring a system. Without some kind of application using the API, it’s difficult to explore and visualize the elegance and simplicity of this kind of interface.

Keeping in line with the simple API, I’ve created a simple application to exercise the API, creating a list of toppings for your virtual pizza. Again, for a real application there would be a full pizza and a method to place the order, but this application is deliberately as simple as possible so it’s easy to understand how it works.

I’ll go through the same sequence I did in the last section. Here’s our starting pizza, with pepperoni, pineapple, and pickles. Loading the initial page causes an API call to be generated, and we get the current list of toppings from the system.

First, take a look at the JSON representation returned when the API is called directly at /api/v1.0/toppings, shown in figure 2.7. Figure 2.8 shows how the application looks when this API call is made on the back end.

Figure 2.7. Here you see a representation of the API toppings list in JSON, the markup language used by the platform. As described, the curly braces indicate an object, or dictionary, and the square brackets represent an array, or list of objects.

Figure 2.8. The application view for the toppings list shows the same information, as shown in figure 2.4. This screen is created by calling the toppings list and creating the HTML based on the returned information. If the list changes on the server, both figure 2.4 and figure 2.5 would change, with both showing the same information in different ways.

Now take a look at the main application at http://irresistibleapis.com/demo. With the JSON data, the simple application can build the front page. Some of the items are static—they don’t change. The top half of the page, for instance, is always the same, with the title of the display and a button to add new toppings. The bottom half, though, is created based on the information retrieved from the API. Each topping is listed, and the ID of the topping is used to create an appropriate button to act on that specific item. The user has no need to understand the relationship between the ID and the name of the topping, but the IDs are used programmatically to set up the page to be functionally correct. Note how the information in the API in figure 2.4 directly maps to what’s shown in the application in figure 2.5. The buttons on this page map directly to the other API calls, as shown in table 2.2.

Table 2.2. The mapping between the API calls and application functions

API call

Application function

GET /api/v1.0/toppings Main application page
GET /api/v1.0/toppings/1 View button on main page
POST /api/v1.0/toppings “Add new topping”
DELETE /api/v1.0/toppings/1 Delete button on either page

As we walk through the API actions, use the HTTP sniffer of your choice to watch the traffic as the interactions happen. Note that because this system is live, other people may have added, deleted, or edited the toppings, and they may not match. Feel free to use the buttons to adjust the toppings to match or follow along with your own favorite toppings (Jalapeños? Sun dried tomatoes? Legos?).

The first action in the previous example was removing the pickles from the pizza, and clicking Delete on this page for the Pickles entry will do that. This button knows which ID to operate on because it was embedded in the page when the listing was rendered.

Clicking the Delete button will make the DELETE call and then make a call to the API to re-render the list of toppings with the deleted topping gone. If you’re using an HTTP sniffer or have configured your browser to show you web traffic, you can see this call happening from your system. Figure 2.9 shows what it looks like in HTTPScoop.

Figure 2.9. This HTTPScoop screen shows a list of all the calls made by the system. In this case, you can see the DELETE method is called to remove the /toppings/2 resource from the system, and it was successful, as indicated by the 2XX response in the code column.

As you can see, the application pulled a few different framework files and then got the full listing for the main page. When I clicked Delete, the application sent a DELETE request to the API server and then requested a new list of toppings. All the requests were successful, so the main page refreshed to show the new list. Figure 2.10 shows the list after I deleted the offending pickles from the toppings list.

Figure 2.10. Once the topping has been deleted from the system, the HTML representation of the toppings list no longer shows the deleted topping. If the platform call is made (to /toppings) you’ll see that the change is reflected in the JSON representation as well.

To edit an existing topping, in this case to change Pepperoni to Ham, click the View button. Doing so makes the read call for the specific item and allows you to edit the title. Using this technique to edit the Pepperoni to Ham and then clicking Save causes a PUT to happen exactly as in the original example. Watch your HTTP sniffer or browser traffic to see how this progression works. Figure 2.11 shows what the Edit page looks like for a particular topping—in this case I changed the title from Pepperoni to Ham. When this change is PUT to the API, it will change the item’s title from Pepperoni to Ham, updating the database to reflect the change permanently.

Figure 2.11. The Edit a Topping screen allows you to change the title of an existing resource.

The PUT request, viewed in HTTPScoop, shows the request and response (see figure 2.12).

Figure 2.12. When you change the title of an existing resource, the information is sent to the server, and it sends back the new representation of that item. In this case, the object is quite simple; the title is the only field that can be changed. This is a simple demonstration of how an update works on an API platform.

As with the associated curl request earlier, the debugging demonstrates that the client sends a request including the new information for the requested item. A PUT request replaces information for an existing item in the system. In the response, the server returns a response showing the new values for the resource. This returned object matches the object that was PUT to the system. Without HTTPScoop, this seems a little magical, but you should be seeing a pattern by this point; these common operations are direct mappings to system calls on the back end of the application.

Again, once the topping is edited, the application redisplays the main page, now with Ham and Pineapple (figure 2.13).

Figure 2.13. The list of toppings now includes Ham and Pineapple; the Pickles have been deleted (thank heavens), and the Pepperoni has been changed to Ham using an update. Again, if you made a call to the /toppings resource you’d see the changes shown in the JSON representation as well.

What’s left then? Now I need to add my extra cheese to the pizza, because it’s my favorite sort of thing. Clicking the Add New Topping button on the main page gives me a page for adding a new topping, as shown in figure 2.14. Remember, adding a new item to the list is a POST action, and that’s what will happen on the back end. Figure 2.15 shows what the API transaction looks like when this POST is sent.

Figure 2.14. The Add a Topping screen is designed to add new toppings to the system. As mentioned earlier, a create action is generally represented by a POST operation, and that’s what the system will do in this case.

Figure 2.15. HTTPScoop POST request/response. The only field needed to create a new topping is the title, and it’s set to Extra extra cheese (yum!). The response shows the ID and title—the entire representation—of the newly added item.

This example demonstrates again the difference between PUT, which updates a specific existing item, and POST, which creates a new item by adding it to the specified list. After adding this new topping to the system, the application again requests the list of toppings, which brings the web page back once again to the main page. This completes the circuit using an application to exercise the back-end API. The single page running this application is quite straightforward, because all the logic and actions are happening on the back end using the API.

Now that you’ve had the opportunity to view some specific traffic, take time to play with the example application with the various HTTP inspection methods. Because this sample application runs in your browser, you have the option of using developer tools in your browser to watch the traffic or an HTTP sniffer for this exploration. For the exercises in this book, you’ll want to use an HTTP sniffer, so pick the one you’re most comfortable with and start familiarizing yourself with its use.

Advanced Example Note

If you’re a developer and want to install your own copy of this system, follow the instructions in section 2.6 to do so. Otherwise, skip to section 2.7 for a summary of this chapter.

2.6. Install your own API and front end

This optional section is designed specifically for developers who want to understand more completely the back-end functionality of the API and sample application. You can use a Docker container to run the system quickly on your own system or download the code from my GitHub repository. I’ll walk through the steps to install and use the Docker container first and then give more general instructions for grabbing the code from GitHub to run on your own system.

2.6.1. Installing the system via Docker

Docker is extremely simple to install on Linux systems and quite easy on Mac OS X and Windows systems as well. Installing the Docker container is simple once you’ve got the Docker system set up. Using this container allows you to separate the code and processes from the main processes on your system while avoiding the memory and space-management issues of more heavyweight virtual machine systems. The Docker installers for installation on Windows and Macintosh are at www.docker.com/toolbox.

If you’re an advanced user running Windows and already have virtualization working via VBox or another virtualization system, you need to be aware that Docker relies on VirtualBox, which may conflict with your existing setup. Additionally, boot2docker requires that virtualization be available on your system, which infrequently requires changes to the BIOS. Also, virtualization is only available on 64-bit systems. If your system is a 32-bit system, you’ll need to install the code directly from GitHub.

Once you’ve installed Docker using the instructions at the Docker website, you’re ready to pull and run the container.

On Linux, issue this command (on one line):

% sudo docker run -p 80:3000 synedra/irresistible

That binds your system’s port 80 to the Docker container on port 3000.

On systems using boot2docker (Windows or Mac OS X), the command is as follows (root access isn’t needed because of the nature of docker-machine):

% docker run -p 80:3000 synedra/irresistible

The application automatically runs in the Docker container. When using boot2docker, the Docker engine assigns a separate IP address for Docker containers. In order to determine the IP address of your Docker container, issue the command docker-machine ip default. Once you’ve done that, you can access the system at http://<docker-ip/. Because the server is running on port 80, the default web port, the browser will find the web server on that port.

If you’d like to start the container and explore the code, you can do so with the following command, which won’t start the node server:

% docker run -i -t synedra/irresistible /bin/bash

You’ll now be root in a shell within the container. Accessing the system in this way allows you to look at the code and figure out how all the pieces are working together. The application itself is composed of the toppings.js file, and the front-end web server is run from the static/index.html file. The previous command will allow you to access the application directly without cross-domain issues. You can read more about Docker port forwarding at https://docs.docker.com/userguide/dockerlinks/.

If you’re running Docker directly on Linux, you can access the system directly at http://localhost. If you already have a web service running on the default port, you can assign a different port in the docker run command.

2.6.2. Installing the system via Git

If you prefer to run the applications on your own system rather than using the Docker container, you need to have Git and Node.js installed on your system. The commands needed to pull the repository to your system and install and run node are as follows:

% git clone https://github.com/synedra/irresistible
% cd irresistible/
% curl -sL https://deb.nodesource.com/setup | bash - && apt-get
 install -yq nodejs build-essential
% npm install -g npm
% npm config set registry  http://registry.npmjs.org/
% npm install -g  [email protected]
% npm install express
% npm install
% node toppings.js

From there you can access the system at http://localhost:3000 (or port 3000 on whichever server you’re using). Node.js runs on port 3000 by default, so if you want to expose the system on the standard port (80), you’ll want to run a separate server on the front end—something like Nginx or Apache—and then create a reverse proxy back to the node server. For security reasons it’s best not to use root to run a bare web service, and you can’t access the standard ports as a regular user. This is one of the advantages to using the Docker system—because it’s isolated from the rest of your system at its own IP address, it’s safe to run the front-end server on port 80.

2.6.3. Exploring the code

As you’re running the system and exploring it, you’ll see the logs for the system show up in the terminal window where you started up the web server. Using an HTTP sniffer, you can watch the API traffic your system is generating as described in section 2.3. Once you’ve started a web browser at http://docker_ip_address/, not only will you be able to see the traffic in an HTTP sniffer, but you’ll start seeing server entries in the terminal window that you started.

The logs show you all the traffic—both front-end calls to / and the back-end requests to the API. This combined log data makes it easy to see how the systems are interacting.

If you used the Docker setup, you were placed directly into the /opt/webapp directory. The Git instructions will put you in the same directory: the webapp subdirectory of the repository. Table 2.3 shows a listing of the files in the program directory along with a description of what each one does.

Table 2.3. Files included in the program directory

Filename

Description

Procfile Used if you want to deploy this to Heroku
Toppings.js The main program for the system
static/index.html A simple single-page application that exercises the API

The toppings.js file is used to run the node web server. When you type node toppings.js, the application looks for the index.html file in the static directory and serves it up.

The application uses Bootstrap, a single-page application framework that makes your simple applications look pretty. The formatting pieces are mostly contained within the Bootstrap framework, and overrides are made within the index.html file. This is all to explain what the id and style attributes are for each <div> on the page. In this case, it’s using the main-single-template for the outside wrapper, and the inside is a main-single container. This function will present the table of items for the page to render.

The $.get function makes the call to /api/v1.0/toppings, at which point the back end returns a list of toppings, and this function is called to render the page.

Exercise 3

Play around with the page, see how each piece works, and try to see if you can make the application go directly to the Edit page from the toppings list instead of the View page.

2.7. Summary

At this point you’ve either played directly with my hosted service or set up your own. This chapter covered the following concepts:

  • The structure of a simple web API system includes the required actions for a complete platform: create, read, update, and delete.
  • A basic HTTP transaction includes a clearly defined request and response, creating a foundation for web APIs.
  • From HTTP sniffers to Chrome Developer Tools, the ability to monitor the traffic makes it much easier to understand what’s happening between the systems.
  • RESTful API ideals define the endpoints as nouns, and not verbs. Between these ideas and the HTTP transactions they work with, the web API system is complete.

Now that you have an understanding of the various moving pieces in a simple API, you can begin thinking about your own API at a higher level: how to architect the entire system to use the simple pieces I discussed here to build a fantastic API system. This chapter was about the bottom up, and how the cogs and wheels work together to make things work. The next chapter will help you to learn how to think top down: what are the goals for your API system and how can you meet them most efficiently?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset