Understanding and Using APIs (4)

 If you plan to automate your network (or even just parts of it), you will want to be able to create and troubleshoot Application Programming Interfaces (APIs). APIs define the way users, developers, and other applications interact with an application's components. With so many APIs to work with, you have to be sure that you understand the foundations. This module concentrates on REST APIs. Cisco has many product lines with these interfaces for multiple use cases, whether collecting data, calling services, or listening to events.

Introducing APIs

What is an API?

An API allows one piece of software talk to another. An API is analogous to a power outlet. Without a power outlet, what would you have to do to power your laptop?

  • Open the wall
  • Unsheath wires
  • Splice wires together
  • Understand all the wires in the wall

An API defines how a programmer can write one piece of software to talk to an existing application’s features or even build entirely new applications.

An API can use common web-based interactions or communication protocols, and it can also use its own proprietary standards. A good example of the power of using an API is a restaurant recommendation app that returns a list of relevant restaurants in the area. Instead of creating a mapping function from scratch, the app integrates a third-party API to provide map functionality. The creator of the API specifies how and under what circumstances programmers can access the interface.

As part of this process, the API also determines what type of data, services, and functionality the application exposes to third parties; if it is not exposed by the API, it is not exposed, period. (That is, assuming security is properly configured!) By providing APIs, applications can control what they expose in a secure way.

The figure shows a rectangular front of a container divided into two main sections. In the top section is API with lines with arrows at both ends going to 4 icons outside the box: cloud service, thin or thick application, mobile application, and scripts. In the bottom section there are three icons and associated words with each icon having a line with arrows on both ends pointing to the API box in the section above. The words are services, applications, and DB.

Example of different types of API integrations.


Think of it like the buttons on the dashboard of your car. When you turn the key or push the Engine ON button to start the car, what you see is that the car starts. You do not see or even care that the engine starts the electronic ignition system which causes the gas to enter the engine and the pistons to start moving. All you know is that if you want the car to start, you turn the key or push the ON Engine button. If you push a different button, such as the radio ON button, the car will not start because that was not the definition that the car (application) defined for starting the engine. The car (application) itself can do many more things than start the engine, but those things are not exposed to the driver (third-party user).

Why use APIs?

APIs are usually built to be consumed programmatically by other applications, which is why they are called Application Programming Interfaces. But they do not have to be used programmatically; they can also be used by humans who want to interact with the application manually.

Here are just a few of the many use cases for APIs:

  • Automation tasks - Build a script that performs your manual tasks automatically and programmatically. Example: You are a manager and on the last day of every pay period, you need to manually log into the portal and download the timecard for each individual who reports to you. Then you need to manually add up the number of hours each person worked so that you can see how much to pay them. If you create an automated script that calls the portal's API to get the data from each timecard and calculate the total from that data, your script can print out a list of total hours worked per person in a user friendly format. Think about how much time that would save!
  • Data integration - An application can consume or react to data provided by another application. Example: Many e-commerce websites use payment services which are accessed via a REST API. The payment interface lets a vendor site transmit relatively low-value data, such as a description of object purchased and the price. The user then independently authenticates to the payment service to confirm the payment. This allows the vendor to receive payment without needing direct access to customer credit card data. The vendor gets back a confirmation code for use by accounting.
  • Functionality - An application can integrate another application's functionality into its product. Example: Many online services, such as Yelp and Uber, exchange data with Google Maps to create and optimize travel routes. They also embed functionality from Google Maps within their own apps and websites to present realtime route maps.

Why are APIs so popular?

APIs have existed for decades, but exposure and consumption of APIs has grown exponentially in the last 10 years or so. In the past, applications were locked down and the only integration between them was through predetermined partnerships. As the software industry has grown, so has the demand for integration. As a result, more and more applications have started to expose bits and pieces of themselves for third-party applications or individuals to use.

Most modern APIs are designed into the product rather than being an afterthought. These APIs are usually thoroughly tested, just like any other component of the product. These APIs are reliable and are sometimes even used by the product itself. For example, sometimes an application's user interface is built on the same APIs that are provided for third parties.

The popularity of easier and more simplified coding languages such as Python have made it possible for non-software engineers to build applications and consume these APIs. They get the results they want without having to hire expensive development talent.

API Design Styles

Types of design styles

APIs can be delivered in one of two ways: synchronously or asynchronously. You need to know the difference between the two, because the application that is consuming the API manages the response differently depending on the API design. Each design has its own purpose, but also its own set of complexities on the client and/or server side. A product’s set of APIs may consist of both synchronous and asynchronous designs, where each API’s design is independent of the others. For best practices, however, the logic behind the design should be consistent.

Synchronous APIs

Synchronous APIs respond to a request directly, usually providing data (or another appropriate response) immediately.

When are APIs synchronous?

APIs are usually designed to be synchronous when the data for the request is readily available, such as when the data is stored in a database or in internal memory. The server can instantly fetch this data and respond back immediately.

Benefits of a synchronous API design

Synchronous APIs enable the application to receive data immediately. If the API is designed correctly, the application will have better performance because everything happens quickly. However, if it is not designed correctly, the API request will be a bottleneck because the application has to wait for the response.

Client side processing

The application making the API request must wait for the response before performing any additional code execution tasks.

Asynchronous APIs


Asynchronous APIs provide a response to signify that the request has been received, but that response does not have any actual data. The server processes the request, which may take time, and sends a notification (or triggers a callback) with the data after the request has been processed. The client can then act on that returned data.

When are APIs asynchronous?

APIs are usually designed to be asynchronous when the request is an action that takes some time for the server to process, or if the data is not readily available. For example, if the server has to make a request to a remote service to fetch the data, it cannot guarantee that it will receive the data immediately to send back to the client. Just because an API is asynchronous does not necessarily mean that the client will not get the data immediately. It only means that an immediate response with data is not guaranteed.

Benefits of an asynchronous API design

Asynchronous APIs let the application continue execution without being blocked for the amount of time it takes for the server to process the request. As a result, the application may have better performance because it can multi-task and make other requests. However, unnecessary or excessive use of asynchronous calls can have the opposite effect on performance.

Client-side processing

With asynchronous processing, the design of the API on the server side defines what you want to do on the client side. Sometimes the client can establish a listener or callback mechanism to receive these notifications and process them when they are received. Depending on the design of the application, your client may also need a queue to store the requests to maintain the order for processing. Other API designs need the client to have a polling mechanism to find out the status and progress of a given request.

API Architectural Styles

Common Architectural Styles

The application defines how third parties interact with it, which means there's no "standard" way to create an API. However, even though an application technically can expose a haphazard interface, the best practice is to follow standards, protocols, and specific architectural styles. This makes it much easier for consumers of the API to learn and understand the API, because the concepts will already be familiar.

The three most popular types of API architectural styles are RPC, SOAP, and REST.

RPC

Remote Procedure Call (RPC) is a request-response model that lets an application (acting as a client) make a procedure call to another application (acting as a server). The "server" application is typically located on another system within the network.

With RPC, the client is usually unaware that the procedure request is being executed remotely because the request is made to a layer that hides those details. As far as the client is concerned, these procedure calls are simply actions that it wants to perform. In other words, to a client, a Remote Procedure Call is just a method with arguments. When it's called, the method gets executed and the results get returned.

The figure shows two columns. The column on the left is labeled Caller (client process) and the column on the right is Callee (server process). A solid arrow goes from caller to call procedure dot. A solid line labeled request points to the callee side dot receive request. Above this dot is a dashed line from callee to a dot labeled wait for request and another dashed line down to receive request. There is a solid line going through a dot labeled process request under the callee column with an arrow pointing to the send response under the callee column. There is a solid line with an arrow going from send response to receive response under the caller column with the line labeled response. On the caller side there is a dashed line going from call procedure dot to the receive response dot and through a dot labeled wait for response. There is a solid arrow pointing downward under the caller column through a dot labeled resume execution. There is a dashed line under the send response dot on the callee side going through a dot labeled wait for request.

Remote Procedure Call client-server request/response model


In the most common usage of RPC, the client makes a synchronous request to the server and is blocked while the server processes the request. When the server is done with the request, it sends a response back to the client, which unblocks its process. (This doesn't apply for asynchronous requests.)

RPC is an API style that can be applied to different transport protocols. Example implementations include:

  • XML-RPC
  • JSON-RPC
  • NFS (Network File System)
  • Simple Object Access Protocol (SOAP)

SOAP

SOAP is a messaging protocol. It is used for communicating between applications that may be on different platforms or built with different programming languages. It is an XML-based protocol that was developed by Microsoft. SOAP is commonly used with HyperText Transfer Protocol (HTTP) transport, but can be applied to other protocols. SOAP is independent, extensible, and neutral.

Independent

SOAP was designed so that all types of applications can communicate with each other. The applications can be built using different programming languages, can run on different operating systems, and can be as different as possible.

Extensible

SOAP itself is considered an application of XML, so extensions can be built on top of it. This extensibility means you can add features such as reliability and security.

Neutral

SOAP can be used over any protocol, including HTTP, SMTP, TCP, UDP, or JMS.

SOAP messages

A SOAP message is just an XML document that may contain four elements:

  • Envelope
  • Header
  • Body
  • Fault
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body>
        <soap:Fault>
            <faultcode>soap:Server</faultcode>
            <faultstring>Query request too large.</faultstring>
        </soap:Fault>
    </soap:Body>
</soap:Envelope>

Example of a SOAP message

Envelope

The Envelope must be the root element of the XML document. In the Envelope, the namespace provided tells you that the XML document is a SOAP message.

Header

The header is an optional element, but if a header is present, it must be the first child of the Envelope element. Just like most other headers, it contains application-specific information such as authorization, SOAP specific attributes, or any attributes defined by the application.

Body

The body contains the data to be transported to the recipient. This data must be in XML format, and in its own namespace.

Fault

The fault is an optional element, but must be a child element of the Body. There can only be one fault element in a SOAP message. The fault element provides error and/or status information.

REST

REpresentational State Transfer (REST) is an architectural style authored by American computer scientist Roy Thomas Fielding in Chapter 5 of his doctoral dissertation, Architectural Styles and the Design of Network-based Software Architectures, in 2000. Roy Fielding defines REST as a hybrid style, derived from several network-based architectural styles he described elsewhere in the paper, "combined with additional constraints that define a uniform connector interface."

Note: Search for Fielding’s dissertation on the internet for more information.

We'll examine REST in detail in the next two sections, but let's look at the basics.

In Fielding's dissertation, he establishes six constraints applied to elements within the architecture:

  • Client-Server
  • Stateless
  • Cache
  • Uniform Interface
  • Layered System
  • Code-On-Demand

These six constraints can be applied to any protocol, and when they are applied, you will often hear that it is RESTful.

Client-Server

The client and server should be independent of each other, enabling the client to be built for multiple platforms and simplifying the server side components.

The figure shows a box labeled client on the left and a computer icon labeled server on the right. A line with dots at both ends go between the two icons.

REST client-server model


Stateless

Requests from the client to the server must contain all of the information the server needs to make the request. The server cannot contain session states.

The figure shows a box labeled client on the left and a computer icon labeled server on the right. A line with dots at both ends go between the two icons.

REST stateless model


Cache

Responses from the server must state whether the response is cacheable or non-cacheable. If it is cacheable, the client can use the data from the response for later requests.

The figure shows a box labeled client on the left and a computer icon labeled server on the right. A line with dots at both ends go between the two icons.

REST cache model



Uniform interface

The interface between the client and the server must adhere to these four principles:

  • Identification of resources - A resource must be identified in the request as the individual object that the server will access and manipulate. A resource can be any information such as a document, image, person, a collection of other resources, and so on. For example, in the request to change a password for a user, the individual user must be identified.
  • Manipulation of resources through representations - The client receives a representation of the resource from the server. This representation must contain enough data or metadata for the client to be able to manipulate the resource. For example, a request intended to populate a user's profile must include the profile information. A representation can be an exact copy of the resource on the server or even a simplified version of the resource but not, for example, just an identifier to an additional resource.
  • Self-descriptive messages - Each message must contain all of the information for the recipient to process the message. Examples of information can be:
    • The protocol type
    • The data format of the message
    • The requested operation
  • Hypermedia as the engine of application state - The data sent by the server must include additional actions and resources available for the client to access supplemental information about the resource.

Layered system

The system is made up of different hierarchical layers in which each layer provides services to only the layer above it. As a result, it consumes services from the layer below.

The figure shows a box labeled client on the left and a computer icon labeled server on the right. A line with dots at both ends go between the two icons.

REST layered system model


Code-on-demand

This constraint is optional, and references the fact that information returned by a REST service can include executable code (e.g., JavaScript) or links to such code, intended to usefully extend client functionality. For example, a payment service might use REST to make available links to its published JavaScript libraries for making payments. These JavaScript files could then be downloaded and (if judged trustworthy) executed by a client application. This eliminates the need for client developers to create and maintain separate payment-processing code, and manage dependency changes that might break such code from time to time.

The constraint is optional because executing third-party code introduces potential security risks, and because firewalls and other policy-management tools may make third-party code execution impossible in some cases.

Introduction to REST APIs


REST Web Service APIs

The figure shows a client box on the left and a computer icon within a cloud and with the word API. An arrow goes from client to API with the words request (H T T P). Another arrow below the type one goes from the cloud to the client with the words response (H T T P).

REST API request/response model


A REST web service API (REST API) is a programming interface that communicates over HTTP while adhering to the principles of the REST architectural style.

To refresh your memory, the six principles of the REST architectural style are:

  1. Client-Server
  2. Stateless
  3. Cache
  4. Uniform Interface
  5. Layered System
  6. Code-On-Demand (Optional)

Because REST APIs communicate over HTTP, they use the same concepts as the HTTP protocol:

  • HTTP requests/responses
  • HTTP verbs
  • HTTP status codes
  • HTTP headers/body

REST API Requests

REST API requests

REST API requests are essentially HTTP requests that follow the REST principles. These requests are a way for an application (client) to ask the server to perform a function. Because it is an API, these functions are predefined by the server and must follow the provided specification.

REST API requests are made up of four major components:

  • Uniform Resource Identifier (URI)
  • HTTP Method
  • Header
  • Body

Uniform Resource Identifier (URI)

The Uniform Resource Identifier (URI) is sometimes referred to as Uniform Resource Locator (URL). The URI identifies which resource the client wants to manipulate. A REST request must identify the requested resource; the identification of resources for a REST API is usually part of the URI.

A URI is essentially the same format as the URL you use in a browser to go to a webpage. The syntax consists the following components in this particular order:

  • Scheme
  • Authority
  • Path
  • Query

When you piece the components together, a URI will look like this : scheme:[//authority][/path][?query]

Scheme

The scheme specifies which HTTP protocol should be used. For a REST API, the two options are:

  • http -- connection is open
  • https -- connection is secure

Authority

The authority, or destination, consists of two parts that are preceded with two forward slashes ( // ):

  • Host
  • Port

The host is the hostname or IP address of the server that is providing the REST API (web service). The port is the communication endpoint, or the port number, that is associated to the host. The port is always preceded with a colon ( : ). Note that if the server is using the default port -- 80 for HTTP and 443 for HTTPS -- the port may be omitted from the URI.

Path

For a REST API, the path is usually known as the resource path, and represents the location of the resource, the data or object, to be manipulated on the server. The path is preceded by a slash ( / ) and can consists of multiple segments that are separated by a slash ( / ).

Query

The query, which includes the query parameters, is optional. The query provides additional details for scope, for filtering, or to clarify a request. If the query is present, it is preceded with a question mark ( ? ). There isn't a specific syntax for query parameters, but it is typically defined as a set of key-value pairs that are separated by an ampersand ( & ). For example:

http://example.com/update/person?id=42&email=person%40example.com

HTTP method

REST APIs use the standard HTTP methods, also known as HTTP verbs, as a way to tell the web service which action is being requested for the given resource. There isn't a standard that defines which HTTP method is mapped to which action, but the suggested mapping looks like this:


Header

REST APIs use the standard HTTP header format to communicate additional information between the client and the server, but this additional information is optional. HTTP headers are formatted as name-value pairs that are separated by a colon ( : ), [name]:[value]. Some standard HTTP headers are defined, but the web service accepting the REST API request can define custom headers to accept.

There are two types of headers: request headers and entity headers.

Request headers

Request headers include additional information that doesn't relate to the content of the message.

For example, here is a typical request header you may find for a REST API request:

Key

Example Value

Description

Authorization

Basic dmFncmFudDp2YWdyYW50

Provide credentials to authorize the request

Entity headers

Entity headers are additional information that describe the content of the body of the message.

Here is a typical entity header you may find for a REST API request:

Key

Example Value

Description

Content-Type

application/json

Specify the format of the data in the body

Body

The body of the REST API request contains the data pertaining to the resource that the client wants to manipulate. REST API requests that use the HTTP method POST, PUT, and PATCH typically include a body. Depending on the HTTP method, the body is optional, but if data is provided in the body, the data type must be specified in the header using the Content-Type key. Some APIs are built to accept multiple data types in the request.

REST API Responses

REST API responses are essentially HTTP responses. These responses communicate the results of a client's HTTP request. The response may contain the data that was requested, signify that the server has received its request, or even inform the client that there was a problem with their request.

REST API responses are similar to the requests, but are made up of three major components:

  • HTTP Status
  • Header
  • Body

HTTP status

REST APIs use the standard HTTP status codes in the response to inform the client whether the request was successful or unsuccessful. The HTTP status code itself can help the client determine the reason for the error and can sometimes provide suggestions for fixing the problem.

HTTP status codes are always three digits. The first digit is the category of the response. The other two digits do not have meaning, but are typically assigned in numerical order. There are five different categories:

  • 1xx - Informational
  • 2xx - Success
  • 3xx - Redirection
  • 4xx - Client Error
  • 5xx - Server Error

1xx - informational

Responses with a 1xx code are for informational purposes, indicating that the server received the request but is not done processing it. The client should expect a full response later. These responses typically do not contain a body.

2xx - success

Responses with a 2xx code mean that the server received and accepted the request. For synchronous APIs, these responses contain the requested data in the body (if applicable). For asynchronous APIs, the responses typically do not contain a body and the 2xx status code is a confirmation that the request was received but still needs to be fulfilled.

3xx - redirection

Responses with a 3xx code mean that the client has an additional action to take in order for the request to be completed. Most of the time a different URL needs to be used. Depending on how the REST API was invoked, the user might be automatically redirected without any manual action.

4xx - client error

Responses with a 4xx code means that the request contains an error, such as bad syntax or invalid input, which prevents the request from being completed. The client must take action to fix these issues before resending the request.

5xx - server error

Responses with a 5xx code means that the server is unable to fulfill the request even though the request itself is valid. Depending on which particular 5xx status code it is, the client may want to retry the request at a later time.

Common HTTP status codes

HTTP Status Code

Status Message

Description

200

OK

Request was successful and typically contains a payload (body)

201

Created

Request was fulfilled and the requested resource was created

202

Accepted

Request has been accepted for processing and is in process

400

Bad Request

Request will not be processed due to an error with the request

401

Unauthorized

Request does not have valid authentication credentials to perform the request

403

Forbidden

Request was understood but has been rejected by the server

404

Not Found

Request cannot be fulfilled because the resource path of the request was not found on the server

500

Internal Server Error

Request cannot be fulfilled due to a server error

503

Service Unavailable

Request cannot be fulfilled because currently the server cannot handle the request

You can get details about each HTTP status code from the official registry of HTTP status codes, which is maintained by the Internet Assigned Numbers Authority (IANA). The registry also indicates which values are unassigned.

Header

Just like the request, the response's header also uses the standard HTTP header format and is also optional. The header in the response is to provide additional information between the server and the client in name-value pair format that is separated by a colon ( : ), [name]:[value].

There are two types of headers: response headers and entity headers.

Response headers

Response headers contain additional information that doesn't relate to the content of the message.

Some typical response headers you may find for a REST API request include:

Key

Example Value

Description

Set-Cookie

JSESSIONID=30A9DN810FQ428P; Path=/

Used to send cookies from the server

Cache-Control

Cache-Control: max-age=3600, public

Specify directives which MUST be obeyed by all caching mechanisms

Entity headers

Entity headers are additional information that describes the content of the body of the message.

One common entity header specifies the type of data being returned:

Key

Example Value

Description

Content-Type

application/json

Specify the format of the data in the body

Body

The body of the REST API response is the data that the client requested in the REST API request. The body is optional, but if data is provided in the body, the data type is specified in the header using the Content-Type key. If the REST API request was unsuccessful, the body may provide additional information about the issue or an action that needs to be taken for the request to be successful.

Response pagination

Some APIs, such as a search API, may need to send a huge amount of data in the response. To reduce the bandwidth usage on the network, these APIs will paginate the response data.

Response pagination enables the data to be broken up into chunks. Most APIs that implement pagination will enable the requester to specify how many items they want in the response. Because there are multiple chunks, the API also has to allow the requester to specify which chunk it wants. There isn't a standard way for an API to implement pagination, but most implementations use the query parameter to specify which page to return in the response. Take a look at the API's documentation to get the pagination details for the specific API you're using.

Compressed response data

When the server needs to send very large amounts of data that cannot be paginated, compressed data is another way to reduce the bandwidth.

This data compression can be requested by the client through the API request itself. To request a data compression, the request must add the Accept-Encoding field to the request header. The accepted values are:

  • gzip
  • compress
  • deflate
  • br
  • identity
  • *

If the server cannot provide any of the requested compression types, it will send a response back with a status code of 406 -- Not acceptable.

If the server fulfills the compression, it will send the response back with the compressed data and add the Content-Encoding field to the response header. The value of the Content-Encoding is the type of compression that was used, enabling the client to decompress the data appropriately.


Using Sequence Diagrams with REST API

Sequence diagrams are used to explain a sequence of exchanges or events. They provide a scenario of an ordered set of events. They are also referred to as event diagrams. While a single REST API request may serve to obtain information or to initiate a change to a system, more commonly, interaction with a particular REST API service will be a sequence of requests. For that reason, sequence diagrams are frequently used to explain REST API request/response and asynchronous activity.

Formalized sequence diagrams are closely linked to and are considered a subset of a standardized modeling system known as Unified Modeling Language (UML). UML includes standardized approaches to other aspects of static resources and process, including standardized ways to diagram and explain user interfaces, class definitions and objects, and interaction behavior. Sequence diagrams are one way to diagram interaction behavior.

In a standard sequence diagram, such as the one below, the Y-axis is ordered and unscaled time, with zero time (t\=0) at the top and time increasing towards the bottom. If an arrow or an exchange is lower down in the diagram, it occurs after those that are above.

The X-axis is comprised of lifelines, represented by titled vertical lines, and exchanges or messages represented by horizontal arrows. A lifeline is any element that can interact by receiving or generating a message. By convention, front-end initiators of a sequence such as a user, a client, or a web browser are placed on the left side of the diagram. Elements such as file systems, databases, persistent storage, and so on, are placed to the right side. Intermediate services, such as a webserver or API endpoints, are arranged in the middle.

One of the useful aspects of sequence diagrams is that users of the diagrams can focus on the interaction between just two lifeline elements. For example, while the rest of a diagram might help set context, REST API users can focus on the interaction between the client and the front-end, or as shown below, the Host HTTP/S Service API endpoint handler.

The API sequence below diagrams three simplified scenarios.

The figure shows five boxes at the top: client, host H T T P / S service A P I endpoint handler, A P I services, Core, and configuration database. Under the client is a dashed line to a solid bar. There is a solid bar all the way down under the host H T T P /S service box. An arrow goes from the top of the client bar to the top of the host H T T P /S service bar. Another arrow goes to the right of the bar and pointing back into the bar further down. At the same point on the left side of the host H T T P /S bar another arrow points to the bottom of the client bar. A dashed line goes from the first client bar to a second client bar. An arrow goes from the top of this bar to the bar under host H T T P / S bar. Another arrow goes out the right side of the host H T T P / S bar to a bar under API services. An arrow goes from the right side of this bar over to a bar under the configuration database bar. An arrow goes out of the top right of this bar back down into the bottom right of this same bar. An arrow goes from the left of this bar back into the bottom right side of the A P I services bar. Another arrow goes from the bottom left A P I services bar into the Host H T T P / S bar. Another arrow goes from the left side of the host H T T P / S bar to the bottom of the second client bar. A dashed line goes down to the third and last bar under the client box. An arrow goes from the top right of the client bar over to the host H T T P /S bar. An arrow goes from the right side of the host H T T P / S bar to a new bar under A P I services. Another arrow goes from the right of the A P I services bar over to a bar under the core box. An arrow goes out of the core box into a small rectangle within the core bar. An arrow goes from the middle left side of the core bar into the right side of the A P I services bar. An arrow goes from the middle left side of the A P I services bar into the host H T T P / S bar. An arrow goes from the left side of the host H T T P /S bar to the client bar. There is also an arrow that goes from that rectangular box within the center of the core bar and the arrow points to a bar under configuration database. An arrow comes out the right side and right back into the bottom of the bar under configuration database. An arrow points to the left to the bottom of the core bar. Another arrow comes out of the left side of the core bar and goes into the bottom of the API services bar. Further down the client bar, an arrow goes from the right side pointing to the host H T T P / S bar. An arrow goes from the right side of the host H T T P /S side into a new bar under A P I services. An arrow comes out of the bottom left side of the API services bar back toward the Host H T T P / S bar. Another arrow goes from the left side of the host H T T P / S bar to the client bar.

API Request/Response Sequence Diagram


The client on the left could be a Python scripted application, POSTMAN test environment, or any other generator of API requests. The client will send an HTTPS formatted request to a server front-end, titled here Host HTTP/S Service API endpoint handler. This component will typically hand off the request to the appropriate API handler, which is named API Services. To the right of API Services, is an element simply named Core, which is a catch-all for the primary processing logic or platform.

API Services may handle some requests directly or may interpret and then forward some or all of a request onto Core. The rightmost column, shown here as Configuration Database, might be any persistent storage - or even a messaging or enqueuing process to communicate with another system.

In this example, there are three separate sequences shown: create session, get devices, and create device.

Create Session: The starting request is labeled HTTPS: Create Session w/credentials. Here, the logic to create an HTTPS session is in the front-end, Host HTTP/S Service API endpoint handler. (This is shown graphically by use of the arrow that loops back.)

Get Devices: The second request from the client is to request a list of devices from the platform. In this sequence, the request is forwarded to the API Services module, which then contains the logic to query the configuration database directly, obtain a list of devices, and return the list to endpoint handler. The handler then wraps the content into an HTTPS response, and returns it to the client, along with an HTTP status code indicating Success.

These first two sequences demonstrate synchronous exchanges, in which a request is followed by a response, and the task is fully completed with Success or Failure.

Create Device: The third sequence starts with a POST request to create a device. In this case, the request migrates to API Services, which then forwards the request to the Core logic, which then starts to work on the request. The API Services wait only for a message from the Core acknowledging that the device creation process has begun. The Core provides a handle (TaskId) that identifies the work and allows follow up to see if the work was completed. The TaskId value propagates in a response back to the client. The HTTP response tells the client only the handle (TaskId) and that the request has been initiated with a response code of 202 (Accepted). This indicates that the request was accepted, and that the work is now in progress.

The Core logic continues to execute. It updates the Configuration Database and then informs the API Services when it is complete. At some later time, the client may choose to confirm that the task completed. The client does this with a Task Status query. API Services can then respond with information about the completion status, and the success or failure status for that task. Because the actual work requested was not completed prior to the response back to the client, this interaction is considered asynchronous.


Authenticating to a REST API

REST API Authentication

Merriam-Webster defines authentication as “…an act, process, or method of showing something (such as an identity) to be real, true, or genuine.” For security reasons, most REST APIs require authentication so that random users cannot create, update or delete information incorrectly or maliciously, or access information that shouldn't be public. Without authentication, a REST API permits anyone to access the features and system services that have been exposed through the interface. Requiring authentication is the same concept as requiring a username/password credential to access the administration page of an application.

Some APIs don't require authentication. These APIs are usually read-only and don't contain critical or confidential information.

Authentication vs Authorization

It's important to understand the difference between authentication and authorization when working with REST APIs, because the two terms are often used interchangeably, or incorrectly. Knowing the difference will help you troubleshoot any issues regarding the security surrounding your REST API request.

Authentication

Authentication is the act of verifying the user's identity. The user is proving that they are who they say they are. For example, when you go to the airport, you have to show your government-issued identification or use biometrics to prove that you are the person you claim to be.

Authorization


Authorization is the user proving that they have the permissions to perform the requested action on that resource. For example, when you go to a concert, all you need to show is your ticket to prove that you are allowed in. You do not necessarily have to prove your identity.

Authentication Mechanisms

Common types of authentication mechanisms include Basic, Bearer, and API Key.

Basic authentication

Basic Authentication, also known as Basic Auth, uses the standard Basic HTTP authentication scheme. Basic Auth transmits credentials as username/password pairs separated with a colon ( : ) and encoded using Base64.

In a REST API request, the Basic Auth information will be provided in the header:

​ Authorization: Basic <username>:<password>

Basic Auth is the simplest authentication mechanism. It is extremely insecure unless it is paired with requests using HTTPS rather than HTTP. Although the credentials are encoded, they are not encrypted. It is simple to decode the credentials and get the username/password pair.

Bearer authentication

Bearer Authentication, also known as Token Authentication, uses the standard Bearer HTTP authentication scheme. It is more secure than Basic Authentication and is typically used with OAuth (discussed later) and Single Sign-On (SSO). Bearer Authentication uses a bearer token, which is a string generated by an authentication server such as an Identity Service (IdS).

In a REST API request, the Bearer Auth information will be provided in the header:

​ Authorization: Bearer <bearer token>

Just like Basic Authentication, Bearer Authentication should be used with HTTPS.

API key

An API key, also referred to as an API Token, is a unique alphanumeric string generated by the server and assigned to a user. To obtain a unique API key, the user typically logs into a portal using their credentials. This key is usually assigned one time and will not be regenerated. All REST API requests for this user must provide the assigned API key as the form of authentication.

Just as with the other types of authentication, API keys are only secure when used with HTTPS.

API keys are intended to be an authentication mechanism, but are commonly misused as an authorization mechanism.

The two types of API keys are public and private.

A public API key can be shared and enables that user to access a subset of data and APIs. Do not share a private key, because it is similar to your username and password. Most API keys do not expire, and unless the key can be revoked or regenerated, if it is distributed or compromised, anyone with that key can indefinitely access the system as you.

A REST API request can provide an API key in a few different ways:

  • Query string: Only recommended for public API keys
  • Header: Uses the Authorization key or a custom key Authorization: <API Key> or Authorization: APIkey <API Key> or APIkey: <API Key>
  • Body data: Uses a unique key as the identifier Content-Type: application/json
  • Cookie: Uses a unique key as the identifier Cookie: API_KEY=<API Key>

Authorization Mechanisms

Authorization mechanisms

Open Authorization, also known as OAuth, combines authentication with authorization. OAuth was developed as a solution to insecure authentication mechanisms. With increased security compared to the other options, it is usually the recommended form of authentication/authorization for REST APIs.

There are two versions of OAuth, simply named OAuth 1.0 and OAuth 2.0. Most of today's REST APIs implement OAuth 2.0. Note that OAuth 2.0 is not backwards compatible.

Defined in the OAuth 2.0 Authorization Framework, “OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.”

Essentially, OAuth 2.0 enables pre-registered applications to get authorization to perform REST API requests on a user's behalf without the user needing to share their credentials with the application itself. OAuth lets the user provide credentials directly to the authorization server, typically an Identity Provider (IdP) or an Identity Service (IdS), to obtain an access token that can be shared with the application.

This process of obtaining the token is called a flow. The application then uses this token in the REST API as a Bearer Authentication. The web service for the REST API then checks the Authorization server to make sure that the token is valid, and that the requester is authorized to perform the request.


API Rate Limits


What are Rate Limits?

REST APIs make it possible to build complex interactions.

Using an API rate limit is a way for a web service to control the number of requests a user or application can make per defined unit of time. Implementing rate limits is best practice for public and unrestricted APIs. Rate limiting helps:

  • avoid a server overload from too many requests at once
  • provide better service and response time to all users
  • protect against a denial-of-service (DoS) attack

Consumers of the API should understand the different algorithm implementations for rate limiting to avoid hitting the limits, but applications should also gracefully handle situations in which those limits are exceeded.

Rate Limit Algorithms

There isn't a standard way to implement rate limiting, but common algorithms include:

  • Leaky bucket
  • Token bucket
  • Fixed window counter
  • Sliding window counter

Leaky bucket

Example of the leaky bucket algorithm

The leaky bucket algorithm puts all incoming requests into a request queue in the order in which they were received. The incoming requests can come in at any rate, but the server will process the requests from the queue at a fixed rate. If the request queue is full, the request is rejected.

With this algorithm, the client must be prepared for delayed responses or rejected requests.

Token bucket


Example of the token bucket algorithm


The token bucket algorithm gives each user a defined number of tokens they can use within a certain increment of time, and those tokens accumulate until they're used. When the client does make a request, the server checks the bucket to make sure that it contains at least one token. If so, it removes that token and processes the request. If there isn't a token available, it rejects the request.

All requests made before token replenishment will be rejected. After the tokens are replenished, the user can make requests again.

For example, an API using the Token Bucket algorithm sets a rate limit of 10 requests per client per hour. If a client makes 11 requests within an hour, the 11th request will be rejected because there are no tokens left. On the other hand, if the client then makes no requests for 6 hours, it can then make 60 requests at once, because those tokens have accumulated.

With this algorithm, the client must calculate how many tokens it currently has in order to avoid rejected requests. It also needs to handle the potential rejected requests by building in a retry mechanism for when the tokens are replenished.

Fixed window counter


The fixed window counter algorithm is similar to the token bucket, except for two major differences:

  • It uses a counter rather than a collection of tokens.
  • The counter cannot be accumulated.

For this algorithm, a fixed window of time is assigned a counter to represent how many requests can be processed during that period. When the server receives a request, the counter for the current window of time is checked to make sure it is not zero. When the request is processed, the counter is deducted. If the limit for that window of time is met, all subsequent requests within that window of time will be rejected. When the next window of time begins, the counter will be set back to the pre-determined count and requests can be processed again.

To go back to our previous example of 10 requests per hour using this algorithm, the 11th request in an hour will still be rejected, but after 6 hours with no requests, the client can still only make 10 requests in a single hour because those "unused" requests were not accumulated.

With this algorithm, the client must know when the window of time starts and ends so that it knows how many requests can be made within that duration of time. Just like the token bucket algorithm, the client must build a retry mechanism so that it can retry the requests when the next window of time has started.

Sliding window counter


The sliding window counter algorithm allows a fixed number of requests to be made in a set duration of time. This duration of time is not a fixed window and the counter is not replenished when the window begins again. In this algorithm, the server stores the timestamp when the request is made. When a new request is made, the server counts how many requests have already been made from the beginning of the window to the current time in order to determine if the request should be processed or rejected. For example, if the rate is five requests per minute, when the server receives a new request, it checks how many requests have been made in the last 60 seconds. If five requests have already been made, then the new request will be rejected.

With this algorithm, the client does not need to know when the window of time starts and ends. It just needs to make sure that the rate limit has not been exceeded at the time of the request. The client also needs to design a way to delay requests if necessary so that it doesn't exceed the allowed rate, and, of course, accommodate rejected requests.

Knowing the Rate Limit

An API's documentation usually provides details of the rate limit and unit of time. In addition, many rate limiting APIs add details about the rate limit in the response's header. Because there isn't a standard, the key-value pair used in the header may differ between APIs. Some commonly used keys include:

  • X-RateLimit-Limit: The maximum number of requests that can be made in a specified unit of time
  • X-RateLimit-Remaining: The number of requests remaining that the requester can make in the current rate limit window
  • X-RateLimit-Reset: The time the rate limit window will reset

The client can use this information to keep track of how many more API requests they can make in the current window, helping the client avoid hitting the rate limit.

Exceeding the Rate Limit

When the rate limit has been exceeded, the server automatically rejects the request and sends back an HTTP response informing the user. In addition, it is common for the response containing the "rate limit exceeded" error to also include a meaningful HTTP status code. Unfortunately, because there isn't a standard for this interaction, the server can choose which status code to send. The most commonly used HTTP status codes are 429: Too Many Requests or 403: Forbidden; make sure your client is coded for the specific API it is using.


Working with Webhooks


What is a Webhook?

A webhook is an HTTP callback, or an HTTP POST, to a specified URL that notifies your application when a particular activity or “event” has occurred in one of your resources on the platform. The concept is simple. Think of asking someone "tell me right away if X happens". That "someone" is the webhook provider, and you are the application.

Webhooks enable applications to get real-time data, because they are triggered by particular activities or events. With webhooks, applications are more efficient because they no longer need to have a polling mechanism. A polling mechanism is a way of repeatedly requesting information from the service, until a condition is met. Imagine needing to ask someone, again and again, "Has X happened yet? Has X happened yet?" Annoying, right? That's polling. Polling degrades the performance of both the client and server due to repeatedly processing requests and responses. Furthermore, polling isn't real-time, because polls happen at fixed intervals. If an event occurs right after the last time you polled, your application won't learn about the changed status until the poll interval expires and the next poll occurs.

Webhooks are also known as reverse APIs, because applications subscribe to a webhook server by registering with the webhook provider. During this registration process, the application provides a URI to be called by the server when the target activity or event occurs. This URI is typically an API on the application side that the server calls when the webhook is triggered.

When the webhook is triggered, the server sends a notification by becoming the caller and makes a request to the provided URI. This URI represents the API for the application, and the application becomes the callee and consumes the request. As a result, for webhooks, the roles are reversed; the server becomes the client and the client becomes the server. Multiple applications can subscribe to a single webhook server.

Examples:

  • The Cisco DNA Center platform provides webhooks that enable third-party applications to receive network data when specified events occur. You can have your application registered with a particular REST endpoint URI that receives a message from Cisco DNAC when a particular event occurs. For example, if a network device becomes unreachable, the Cisco DNAC webhook can send an HTTP POST to the URI your app has registered on the Cisco DNAC. Your application then receives all the details of the outage in a JSON object from that HTTP POST so it can take action as appropriate. In this case, Cisco DNAC is the webhook provider.
  • You can create a webhook to have Cisco Webex Teams notify you whenever new messages are posted in a particular room. This way, instead of your app making repeated calls to the Teams API to determine whether a new message has been posted, the webhook automatically notifies you of each message. In this case, Cisco Webex Teams is the webhook provider.

Consuming a Webhook

Consuming a webhook

In order to receive a notification from a webhook provider, the application must meet certain requirements:

  • The application must be running at all times to receive HTTP POST requests.
  • The application must register a URI on the webhook provider so that the provider knows where to send a notification when target events occur.

In addition to these two requirements, the application must handle the incoming notifications from the webhook server.

Because working with webhooks involves third parties, it can sometimes be challenging to ensure everything is working properly. There are many free online tools that ensure your application can receive notifications from a webhook. Many can also give you a preview of the content provided in the webhook notification. These tools can be found by searching for "webhook tester", and can be useful when designing and implementing your application.

Troubleshooting API Calls

Troubleshooting REST API Requests

You have learned about REST APIs and explored them in a lab. In the provided scenarios, everything was working properly and was always successful. Of course, in real life, that is not always the way things work. At some point, you will find yourself making REST API requests and not getting the response that you expected. In this part, you will learn how to troubleshoot the most common REST API issues.

Note that when you apply these concepts and troubleshooting tips to a particular REST API, make sure you have the API reference guide and API authentication information handy; it will make your job a lot easier.

No Response and HTTP Status Code from the API server

Let's start with a simple question:

True or false: every request that is sent to the REST API server will return a response with a status code.

The answer is false. While one might expect to always receive an HTTP status code such as 2xx, 4xx and 5xx, there are many cases where the API server cannot be reached or fails to respond. In those scenarios, you will not receive an HTTP status code because the API server is unable to send a response.

While a non-responsive server can be a big issue, the root cause of the unresponsiveness can be simple to identify. You can usually identify what went wrong from the error messages received as a result of the request.

Let's look at some troubleshooting tips to help you debug why the API server didn't send a response and HTTP status code, as well as some potential ways to fix the problem.

Client side error

The first thing to check is whether you have a client-side error; it is here that you have more control in terms of fixing the issue.

Is there a user error?

Some questions to ask to isolate errors from the user include:

  • Is the URI correct?
  • Has this request worked before?

When using a REST API for the first time, mistyping the URI is common. Check the API reference guide for that particular API to verify that the request URI is correct.

Invalid URI example

To test the invalid URI condition, run a script such as this one, which simply makes the request to a URI that is missing the scheme. You can create a Python file or run it directly in a Python interpreter.

import requests
uri = "sandboxdnac.cisco.com/dna/intent/api/v1/network-device"
resp = requests.get(uri, verify = False)

The traceback will look like this:

....requests.exceptions.MissingSchema: Invalid URL 'sandboxdnac.cisco.com/dna/intent/api/v1/network-device': No schema supplied. Perhaps you meant http://sandboxdnac.cisco.com/dna/intent/api/v1/network-device?....

Wrong domain name example

To test the wrong domain name condition, run a script such as this one, which simply makes the request to a URI that has the wrong domain name.

import requests
url = "https://sandboxdnac123.cisco.com/dna/intent/api/v1/network-device"
resp = requests.get(url, verify = False)

The traceback will look like this:

....requests.exceptions.ConnectionError: HTTPSConnectionPool(host='sandboxdnac123.cisco.com', port=443): Max retries exceeded with url: /dna/intent/api/v1/network-device (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x109541080>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))....

Is there a connectivity issue?

If the URI is correct, it may still be inaccessible. Ask yourself these questions:

  • Are there any Proxy, Firewall or VPN issues?
  • Is there an SSL error?

Invalid certificate example

This issue can only occur if the REST API URI uses a secure connection (HTTPS).

When the scheme of the URI is HTTPS, the connection will perform an SSL handshake between the client and the server in order to authenticate one another. This handshake needs to be successful before the REST API request is even sent to the API server.

When using the requests library in Python to make the REST API request, if the SSL handshake fails, the traceback will contain requests.exceptions.SSLError.

For example, if the SSL handshake fails due to the certificate verification failing, the traceback will look like this:

requests.exceptions.SSLError: HTTPSConnectionPool(host='xxxx', port=443): Max retries exceeded with url: /dna/intent/api/v1/network-device (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1108)')))

In this situation, you must fix the invalid certificate. But, if you are working in a lab environment where the certificates aren't valid yet, you can turn off the certificate verification setting.

To turn it off for the requests library in Python, add the verify parameter to the request.

resp = requests.get(url, verify = False)

Resolution: Client errors are usually simple to fix, especially when the error messages in the traceback indicate what may be wrong and the possible solution. Analyze the logs carefully for the root cause.

Server side error

After you've verified that there aren't any client-side errors, the next thing to check are server-side errors.

Is the API server functioning?

The most obvious place to start is to make sure that the API server itself is functioning properly. There are a few things you will want to ask yourself:

  • Is the power off?
  • Are there cabling issues?
  • Did the domain name change?
  • Is the network down?

To test if the IP address is accessible, run a script such as this one, which simply makes the request to the URL and waits for a response.

**Warning**: Expect a long delay when running this script.
import requests
url = "https://209.165.209.225/dna/intent/api/v1/network-device"
resp = requests.get(url, verify = False)

Note: The IP address in this script is bogus, but the script produces the same result as a server that is unreachable.

If the API server is not functioning, you'll get a long silence followed by a traceback that looks like this:

....requests.exceptions.ConnectionError: HTTPSConnectionPool(host='209.165.209.225', port=443): Max retries exceeded with url: /dna/intent/api/v1/network-device (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x10502fe20>: Failed to establish a new connection: [Errno 60] Operation timed out'))....

Is there a communication issue between the API server and the client?

If the server is functioning properly, you'll need to determine whether there's a reason the client isn't receiving a response. Ask yourself:

  • Is the IP address and domain name accessible from the client's location on the network?
  • Is the API server sending a response, but the client isn't receiving it?

To test this condition, use a network capturing tool to see if the response from the API server is lost in the communication between the API server and the client. If you have access, take a look at the API server logs to determine if the request was received, if it was processed, and if a response was sent.

Resolution: Server side issues cannot be resolved from the API client side. Contact the administrator of the API server to resolve this issue.

Interpreting Status Codes

Because REST APIs are http-based, they also use http status codes to notify API clients of request results.

Unless otherwise stated, the status code is part of the HTTP/1.1 standard (RFC 7231), which means the first digit of the status code defines the class of response. (The last two digits do not have any class or categorization role, but help distinguish between results.) There are 5 of these categories:

  • 1xx: Informational: Request received, continuing to process.
  • 2xx: Success: The action was successfully received, understood, and accepted.
  • 3xx: Redirection: Further action must be taken in order to complete the request.
  • 4xx: Client Error: The request contains bad syntax or cannot be fulfilled.
  • 5xx: Server Error: The server failed to fulfill an apparently valid request.

Typically we see 2xx, 4xx and 5xx from the REST API server. Usually you can find the root cause of an error when you understand the meaning of the response codes. Sometimes the API server also provides additional information in the response body.

For all requests that have a return status code, perform these steps to troubleshoot errors:

Step 1: Check the return code. It can help to output the return code in your script during the development phase.

Step 2: Check the response body. Output the response body during development; most of the time you can find what went wrong in the response message sent along with the status code.

Step 3: If you can't resolve the issue using the above two steps, use the status code reference to understand the definition of the status code.

2xx and 4xx Status Codes

Let us look at these codes in more detail:

2xx - Success

When the client receives a 2xx response code, it means the client's request was successfully received, understood, and accepted. However, you should always verify that the response indicates success of the right action and that the script is doing what you think it should.

4xx - Client side error

A 4xx response means that the error is on the client side. Some servers may include an entity containing an explanation of the error. If not, here are some general guidelines for troubleshooting common 4xx errors:

  • 400 - Bad Request

The request could not be understood by the server due to malformed syntax. Check your API syntax.

One cause of a 400 Bad Request error is the resource itself. Double-check the endpoint and resource you are calling, did you misspell one of the resources or forget the "s" to make it plural, such as /device versus /devices or /interface versus /interfaces? Is the URI well-formed and complete?

Another cause of a 400 Bad Request error might be a syntax issue in the JSON object that represents your POST request.

Let us look at an imaginary example service:

import requests
url = "http://myservice/api/v1/resources/house/rooms/id/"
resp = requests.get(url,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)

Can you guess what is wrong just by reading the code?

This example returns a status code of 400. The server side also tells you "No id field provided", because the id is mandatory for this API request. You would have to look that up in the documentation to be sure.

import requests
url = "http://myservice/api/v1/resources/house/rooms/id/1001001027331"
resp = requests.get(url,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)
  • 401 - Unauthorized

This error message means the server could not authenticate the request.

Check your credentials, including username, password, API key, token, and so on. If there are no issues with those items, you may want to check the request URI again, because the server may reject access in the case of an improper request URI.

import requests
url = "http://myservice/api/v1/resources/house/rooms/all"
resp = requests.get(url,verify = False)
print (resp.status_code)
print (resp.text)

This example returns a status code 401, can you guess what is wrong just by reading the code?

The request isn't providing a credential. The authentication auth=("person1","great") should be added in the code.

import requests
url = "http://myservice/api/v1/resources/house/rooms/all"
resp = requests.get(url,auth=("person1","great"),verify = False)
print (resp.status_code)
print (resp.text)
  • 403 - Forbidden

In this case, the server recognizes the authentication credentials, but the client is not authorized to perform the request. Some APIs, such as Cisco DNA Center, have Role Based Access Control, and require a super-admin role to execute certain APIs. Again, the API reference guide may provide additional information.

import requests
url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.get(url,auth=("person1","great"),verify = False)
print (resp.status_code)
print (resp.text)

Why is this imaginary code snippet not working? We just used the username person1 and the password great and it worked in last example.

The status code 403 is not an authentication issue; the server believes in the user's identity, it is just that the user does not have enough privileges to use that particular API. If we use person2/super as username/password for the authentication, it will work, because person2 has the privilege to execute this API. Can you envision how to make it work?

The authentication should be modified to use person2/super instead of person1/great.

import requests
url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.get(url,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)
  • 404 - Not Found

The server has not found anything matching the request URI; check the request URI to make sure it is correct. If the code used to work, you may want to check the latest API reference guide, as an API's syntax can change over time.

Consider the Cisco DNA Center "get all interfaces" API. The title says, "all interfaces", so you try to use api/v1/interfaces, but you get a 404 error because the API request is actually api/v1/interface.

import requests
url = "http://myservice/api/v1/resources/house/room/all"
resp = requests.get(url,auth=("person1","great"),verify = False)
print (resp.status_code)
print (resp.text)

Why did this script return a 404 status code, and can you guess how to fix it?

The actual URI is /api/v1/resources/house/rooms/all. There is no room resource, so the server was unable to find a resource matching the URI of the request.

import requests
url = "http://myservice/api/v1/resources/house/rooms/all"
resp = requests.get(url,auth=("person1","great"),verify = False)
print (resp.status_code)
print (resp.text)
  • 405 - Method Not Allowed

In this case, the request was recognized by the server, but the method specified in the request has been rejected by the server. You may want to check the API reference guide to see what methods the server expects. The response from server may also include an Allow header containing a list of valid methods for the requested resource.

For example, if you mistakenly use the POST method for an API that expects the GET method you will receive a 405 error.

import requests
url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.post(url,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)
  • 406 - Not Acceptable

This error indicates that the target resource does not have a current representation that would be acceptable to the client. The server has the data, but cannot represent it using any of the options listed in the client's Accept- headers.

For example, the client is asking for SVG images: Accept: image/svg+xml

import requests
headers = {'Accept': 'image/svg+xml'}
url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.get(url,headers=headers,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)

In this case, the server does not support the requested resource, image/svg+xml, so it responds with a 406 error.

  • 407 - Proxy Authentication Required

This code is similar to 401 (Unauthorized), but indicates that the client must first authenticate itself with the proxy. In this scenario, there is a proxy server between the client and server, and the 407 response code indicates that client needs to authenticate with the proxy server first.

  • 409 - The request could not be completed due to a conflict with the current state of the target resource.

For example, an edit conflict where a resource is being edited by multiple users would cause a 409 error. Retrying the request later might succeed, as long as the conflict is resolved by the server.

  • 415 - Unsupported Media Type

In this case, the client sent a request body in a format that the server does not support. For example, if the client sends XML to a server that only accepts JSON, the server would return a 415 error.

import requests
headers = {"content-type":"application/xml"}
url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.get(url,headers=headers,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)

From the error message, can you guess a what could fix the code?

Omitting the header or adding a header {"content-type":"application/json"} will work.

import requests
headers = {"content-type":"application/json"}

url = "http://myservice/api/v1/resources/house/rooms/id/1"
resp = requests.get(url,headers=headers,auth=("person2","super"),verify = False)
print (resp.status_code)
print (resp.text)

These are just the most common 4xx response codes. If you encounter other 4xx response codes, you can refer to either RFC 2616, 6.1, Status-Line or RFC 7231, section 6, Response Status Codes for more information on what they mean.

5xx Status Codes

5xx server side error

A 5xx response indicates a server side error.

  • 500 - Internal Server Error

This error means that the server encountered an unexpected condition that prevented it from fulfilling the request.

  • 501 - Not Implemented

This error means that the server does not support the functionality required to fulfill this request. For example, the server will respond with a 501 code when it does not recognize the request method and is therefore incapable of supporting it for any resource.

  • 502 - Bad Gateway

This error means that the server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.

  • 503 - Service Unavailable

This code indicates that the server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be resolved after a delay.

  • 504 - Gateway Timeout

This error means that the server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request.

If you get a 500 or 501 error, check the API reference guide to make sure the request is valid. For other 5xx errors, check with your API server administrator to resolve the issue.

Before you start troubleshooting your API, it is crucial to have your API reference guide and status code references in hand. If you are unable to receive a response code, you will likely be able to identify the cause from the error log in your script. If you are able to receive a response code, you will be able to identify the root cause of the error, including whether the error is on the client or server side, by understanding the response code.

Understanding and Using APIs Summary


What Did I Learn in this Module?

Introducing APIs

An Application Programming Interface (API) defines the ways users, developers, and other applications can interact with an application's components. An API can use common web-based interactions or communication protocols, and it can also use its own proprietary standards. Some use cases are automation tasks, data integration, and functionality. Most modern APIs are designed into the product. These APIs are usually thoroughly tested, are reliable, and are sometimes even used by the product itself.

API Design Styles

APIs can be delivered synchronously or asynchronously. Synchronous APIs respond to a request directly, usually providing data (or another appropriate response) immediately. Asynchronous APIs provide a response to signify that the request has been received, but that response doesn’t have any actual data. The server processes the request, which may take time, and sends a notification (or triggers a callback) with the data after the request has been processed. The client can then act on that returned data.

API Architectural Styles

The three most popular types of API architectural styles are RPC, SOAP, and REST.

Remote Procedure Call (RPC) is a request-response model that lets an application (acting as a client) make a procedure call to another application (acting as a server). The "server" application is typically located on another system within the network.

Simple Object Access Protocol (SOAP) is a messaging protocol. It is used for communicating between applications that may be on different platforms or built with different programming languages. It is an XML-based protocol and is commonly used with HyperText Transfer Protocol (HTTP) transport, but can be applied to other protocols. SOAP is independent, extensible, and neutral.

REpresentational State Transfer (REST) is an architectural style that was created as a hybrid style, derived from several network-based architectural styles that are combined with additional constraints that define a uniform connector interface. There are six constraints applied to elements within the architecture: Client-Server, Stateless, Cache, Uniform Interface, Layered System, and Code-On-Demand. These six constraints can be applied to any protocol, and when they are applied, you will often hear that it is RESTful.

Introduction to REST APIs

A REST web service API (REST API) is a programming interface that communicates over HTTP while adhering to the principles of the REST architectural style. REST API requests are essentially HTTP requests that follow the REST principles. These requests are a way for an application (client) to ask the server to perform a function. REST API responses are essentially HTTP responses. These responses communicate the results of a client's HTTP request. The response may contain the data that was requested, signify that the server has received its request, or even inform the client that there was a problem with their request. Sequence diagrams are used to explain a sequence of exchanges or events. They provide a scenario of an ordered set of events. They are also referred to as event diagrams.

Authenticating to a REST API

For security reasons, most REST APIs require authentication so that random users cannot create, update or delete information incorrectly or maliciously, or access information that shouldn't be public. Without authentication, a REST API permits anyone to access the features and system services that have been exposed through the interface. Authentication is the act of verifying the user's identity. The user is proving that they are who they say they are. Authorization is the user proving that they have the permissions to perform the requested action on that resource. Common types of authentication mechanisms include Basic, Bearer, and API Key. Open Authorization, also known as OAuth, combines authentication with authorization.

API Rate Limits

Using an API rate limit is a way for a web service to control the number of requests a user or application can make per defined unit of time. Common rate limit algorithms include: Leaky bucket, Token bucket, Fixed window counter, and Sliding window counter. Many rate limiting APIs add details about the rate limit in the response's header. Because there is no standard, the key-value pair used in the header may differ between APIs. Some commonly used keys include:

● X-RateLimit-Limit: The maximum number of requests that can be made in a specified unit of time

● X-RateLimit-Remaining: The number of requests remaining that the requester can make in the current rate limit window

● X-RateLimit-Reset: The time the rate limit window will reset

When the rate limit has been exceeded, the server automatically rejects the request and sends back an HTTP response informing the user. In addition, it is common for the response containing the "rate limit exceeded" error to also include a meaningful HTTP status code.

Working with Webhooks

A webhook is an HTTP callback, or an HTTP POST, to a specified URL that notifies your application when a particular activity or “event” has occurred in one of your resources on the platform. Webhooks enable applications to get real-time data, because they are triggered by particular activities or events. With webhooks, applications are more efficient because they no longer need to have a polling mechanism. In order to receive a notification from a webhook provider, the application must be running at all times to receive HTTP POST requests, and it must register a URI on the webhook provider so that the provider knows where to send a notification when target events occur. In addition to these two requirements, the application must handle the incoming notifications from the webhook server.

Troubleshooting API Calls

Before you troubleshoot, make sure you have the API reference guide and API authentication information handy.

It is not true that every request that is sent to the REST API server will return a response with a status code. While one might expect to always receive a HTTP status code such as 2xx, 4xx and 5xx, there are many cases where the API server cannot be reached or fails to respond. In those scenarios, you will not receive an HTTP status code because the API server is unable to send a response.

While a non-responsive server can be a big issue, the root cause of the unresponsiveness can be simple to identify. You can usually identify what went wrong from the error messages received as a result of the request. It could be client side error, user error, wrong URI, wrong domain, a connectivity issue, an invalid certificate, a server side error, or a communication problem between the server and the client. How do you narrow it down? By correctly interpreting status codes. 4xx codes are Client side error and 5xx codes are Server side errors.


Module 4: Understanding and Using APIs Quiz

  1. What is REST?

    Topic 4.3.0 - REST is not a protocol or service, but rather a style of software architecture for designing web service applications.

  2. Which HTTP response status code indicates that the request to update the database is completed?

    Topic 4.4.0 - The most common HTTP status codes include the following:

    • 200 – OK (using GET or POST to exchange data with an API successfully)
    • 201 – Created (creating resources by using a REST API call successfully)
    • 400 – Bad Request (The request from the client is failed due to client-side issue.)
    • 401 – Unauthorized (The client is not authenticated to access site or API call.)
    • 403 – Forbidden (The access request is not granted based on the supplied credentials.)
    • 404 – Not Found (The page requested at HTTP URL location does not exist or is hidden.)
  3. How many elements does a SOAP message contain?

    Topic 4.3.0 - A SOAP message is an XML document that can contain four elements, namely, Envelope, Header, Body, and Fault.

  4. The exhibit shows two boxes. The top box shows a piece of code:<br>import requests<br>uri = "sandboxdnac.cisco.com/dna/intent/api/v1/network-device"<br>resp = requests.get(uri, verify = False)<br>The bottom box shows a traceback message:<br>Traceback message:<br><br>....requests.exceptions.MissingSchema: Invalid URL ''sandboxdnac.cisco.com/dna/intent/api/v1/network-device'

    Refer to the exhibit. A network administrator is using a Python script to test a REST API request. The traceback message indicates there is an error in the URI. What is the error?

    Topic 4.8.0 - The error message indicates “MissingSchema”. A REST API request URI needs the URI to use the proper HTTP protocol, HTTP or HTTPS.

  5. Which type of encoding is used in basic authentication for REST APIs?

    Topic 4.5.0 - REST APIs use Base64 encoding for the basic authentication. Base64 is a binary-to-text encoding scheme.

  6. What is an architectural constraint to which a true RESTful API web service must adhere?

    Topic 4.3.0 - Conforming to the constraints of the REST architecture is generally referred to as being “RESTful”. An API can be considered “RESTful” if it has the following features:

    • Client/server - The client handles the front end and the server handles the back end.
    • Stateless - No client data is stored on the server between requests. The session state is stored on the client.
    • Cacheable - Clients can cache responses locally to improve performance.
  7. What is a reason that a network engineer would use APIs?

    Topic 4.1.0 - Application programming interfaces or APIs interact with one or more applications. APIs are commonly used to automate tasks, to facilitate data integration, and to increase the functionality of another application. Non-software engineers can now use APIs to automate configuration or data collection from network devices.

  8. What is a webhook for REST APIs?

    Topic 4.7.0 - A webhook is an HTTP callback, or an HTTP POST, to a specified URL that notifies the client application when a particular activity or event has occurred in one of the resources on the platform.

  9. As part of creating an API request using Python, the following commands are entered. What is the purpose of this step?
    ipaddr = 10.1.50.1
    interface = Ethernet1/1
    hostname = R1

    Topic 4.9.0 - When a script is being coded or created, a variable can be used to store information. The variable name is to the left and the value is to the right.

  10. A web service uses a rate limit algorithm that puts all incoming REST API requests into a queue in the order in which they arrive. The algorithm allows incoming requests to arrive at any rate, but the server processes the requests from the queue at a fixed rate. Which rate limit algorithm is used by the web service?

    Topic 4.6.0 - Common rate limit algorithms include the following:

    • Leaky bucket
    • Token bucket
    • Fixed window counter
    • Sliding window counter

    The leaky bucket algorithm puts all incoming requests into a request queue in the order in which they were received. The incoming requests can come in at any rate, but the server will process the requests from the queue at a fixed rate. If the request queue is full, the request is rejected.

  11. What is an application requirement in order to receive a notification from a webhook provider?

    Topic 4.7.0 - In order to receive a notification from a webhook provider, the client application must meet certain requirements:

    • The application must always be running to receive HTTP POST requests.
    • The application must register a URI on the webhook provider, so that the provider knows where to send a notification when target events occur.
    • The application must handle the incoming notifications from the webhook server.
  12. Which RESTful operation corresponds to the HTTP GET method?

    Topic 4.4.0 - RESTful operations correspond to the following HTTP methods (shown to the left with the RESTful operation on the right):

    • POST > Create
    • GET > Read
    • PUT/PATCH > Update
    • DELETE > Delete

Ref : [1]

Modul exam 4