Skip to main content

An Introduction to APIs for the Uninitiated

· 7 min read
Software Engineer

APIs or Application Programming Interfaces are, like their name implies, an interface to an application that allows other systems to interact with them programmatically. In this post, we'll discuss some foundational concepts and distill the lexicon associated with APIs into tangible knowledge.

Client-Server Model

Request and Response

A typical interaction across the web can be shown using the Client-Server model. In this case, the client, such as web browser, mobile app or other program, makes requests to a server to retrieve data such as web page or data. The server then responds to the client with either the requested data or some sort of error message.

A diagram of the client server model

This communication occurs using a protocol, such as HTTP, which defines the format of the request and response. The following example shows a bit of what this looks like under the hood.

Request

This is an HTTP request. It is requesting (e.g. GET) a resource (e.g. /articles/index.html) from the server (e.g. jdkaplan.com).

> GET /articles/index.html HTTP/1.1
> Host: jdkaplan.com
> User-Agent: curl/7.71.1
> Accept: */*
Response

This is the response. It is a 200 OK response, which means that the request was successful. The response body is the HTML for the requested page. What is shown here is just the metadata - the part of the response that tells us information about the response such as the status (success or fail), content type, and content length. The actual response body would follow this and contain all of the data requested, in this case an HTML page.

< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 27726
< Connection: keep-alive
< Date: Mon, 07 Jun 2021 20:26:07 GMT
< Last-Modified: Mon, 07 Jun 2021 00:54:26 GMT
< ETag: "a6e163063f3137d5db457cfabb097736"
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Accept-Encoding
< X-Cache: Miss from cloudfront
< Via: 1.1 f9ae6e33f293d8a4e80f48fca6093c68.cloudfront.net (CloudFront)

...

For a deeper dive into this topic, read the Background section of my post on web development basics.

Server Rendered Applications

This is how web pages are typically served. When you type a URL into your web browser, the browser makes a request to the server. The server responds with some HTML, or Hypertext Markup Language, which tells the browser what to render on the page.

You can see a simple example example of this in my previous article on web development basics. You can also do this interactively by opening up the developer tools in your browser and exploring the network tab.

Asynchronicity

In the previous example, the client makes a request and waits for the response before doing anything else. This is called a synchronous request. In practice, this is not how things work. Instead, the client makes a request and when the response comes back, the client is notified and can handle the response. This is called an asynchronous request.

This is commonly used by synchronously requesting a web page which in turn runs some Javascript which makes asynchronous requests to the server to retrieve additional data needed to render the application.

To learn more about asynchronous Javascript, read my introductory post on the topic or take a deeper dive with my Javascript Asynchronicity Patterns article.

Historical Note

Server-rendered applications are still widely-used these days, but there has been a major paradigm shift over the last decade or so (as of this writing) towards

single-page applications, which tend to be more common. In the single-page application approach, the server returns a simple HTML page and a large Javascript bundle that dynamically renders the application.

Data Formats

Web servers can send data in a number of different formats. In the examples above, we saw HTML, the language used to render web applications. When data is being exchanged between applications, it is often sent in formats more geared towards data exchange.

JSON

JSON or Javascript Object Notation is one of the most common formats for exchanging data between applications. It consists of key-value pairs.

{
"name": "John",
"age": 30,
"cars": [
{ "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
{ "name":"BMW", "models":[ "320", "X3", "X5" ] },
{ "name":"Fiat", "models":[ "500", "Panda" ] }
]
}

While it's syntax derives from Javascript object, it is similar to Python dictionaries and data structures native to other languages. This makes it a format that is easy to use from many different programming languages.

XML

XML or Extensible Markup Language is another common format for exchanging data between applications. It consists of tags and attributes.

<cars>
<car name="Ford">
<model>Fiesta</model>
<model>Focus</model>
<model>Mustang</model>
</car>
<car name="BMW">
<model>320</model>
<model>X3</model>
<model>X5</model>
</car>
<car name="Fiat">
<model>500</model>
<model>Panda</model>
</car>
</cars>

APIs

REST APIs

REST or Representational State Transfer is a common term. But what is it? The definition of REST is often unclear. This is because there isn't a standard definition for the term. The general idea is that the API is a collection of resources that can be manipulated via HTTP requests.

Resources are represented by nouns (e.g. users, posts, comments, etc.) and are manipulated via HTTP verbs (e.g. GET, POST, PUT, DELETE, etc.).

  • GET requests are used to retrieve resources.
  • POST requests are used to create resources.
  • PUT requests are used to update resources.
  • DELETE requests are used to delete resources.
PUT vs. PATCH

HTTP methods PUT and PATCH are often misused. This is because PATCH is not part of the original

HTTP specification but is defined in RFC 5789. In short, PUT should replace or create a resource while PATCH should modify a resouce.

Here's an example of a REST API:

GET /users/1 HTTP/1.1
Host: api.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 123

{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}

The above example is a GET request to the /users/1 endpoint. The response is a JSON object with the user's information.

The server implementation might look something like this:

from flask import Flask, jsonify

app = Flask(__name__)

users = {
"1": {
"name": "John Doe",
"email": "john.doe@example.com"
},
"2": {
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
}

@app.route("/users/<user_id>", methods=["GET"])
def get_user(user_id):
user = users.get(user_id)
if user is None:
return jsonify({"success": False, "message": "User not found"}), 404
return jsonify({"success": True, "user": user}), 200

if __name__ == "__main__":
app.run()

For some API design best practices, I recommend Microsoft's article on the topic.

GraphQL APIs

There are other types of APIs besides REST. One of the most popular alternatives is GraphQL. GraphQL is a query language for APIs.

Here's and example GraphQL query:

query {
user(id: "1") {
name
email
}
}

And here's the corresponding response:

{
"data": {
"user": {
"name": "John Doe",
"email": "john.doe@example.com"
}
}
}

And heres what the server-side implementation might look like in Python:

from flask import Flask
from flask_graphql import GraphQLView
from graphene import ObjectType, String, Schema

data = {
'users': {
"1": "John Doe",
"2": "Jane Doe"
}
}

class Query(ObjectType):
user = String(id=String(default_value="1"))

def resolve_user(self, info, id):
return data['users'][id]

schema = Schema(query=Query)
app = Flask(__name__)

@app.route('/graphql', methods=['POST'])
def graphql_view():
return GraphQLView.as_view('graphql', schema=schema, graphiql=True)

if __name__ == '__main__':
app.run()

And here's what the client-side implementation might look like in Javascript:

const query = `
query {
user(id: "1") {
name
email
}
}
`;

const response = await fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({ query })
});

const json = await response.json();
console.log(json.data.user.name);

Other Types of APIs

There are a number of other types of APIs that we won't discuss in detail here, such as Remote Procedure Call (RPC) APIs and SOAP APIs. These are all technologies that are still in use today, but are not as common as REST and GraphQL.

Closing Remarks

There's a lot more to APIs than what we've covered here. My hope is that your takeway from this is an understanding of what an API is, a better understanding of what REST and GraphQL are and how they differ so that you can engage more deeply on the topic going forward.