Creating a Banking API, Part 2

Chris Hailey
5 min readApr 13, 2019

--

In this series, I’ll be developing a (lightweight) banking API. Note that if you want to develop your own API, definitely check out this site: https://www.codementor.io/sagaragarwal94/building-a-basic-restful-api-in-python-58k02xsiq. Much of the code that I write for this project will be based on what Sagar wrote, so a big shout out to him for the helpful guide!

NOTE: If you haven’t read Part 1, please check it out.

Intro

In Part 1, I introduced this BaaS API I’ll be creating for the USC Credit Union, my university’s financial service provider, and began to design the attributes in the database that would be needed to have a functional and useful API.

A USC Credit Union ATM

In this section, I’ll be discussing how to turn that SQL database design into code and how to verify that the API is working once you have a simple server running. If you would like to follow along on this project, check out the GitHub!

API Class Design

In the last part, we started off with the database design. But how do we move from a bunch of tables on a relational database to a working backend server? Well, it turns out, for each Table that we created in SQLite, we would need to create a Class on the backend server (well, at least one, but more on that later). I’ll be using Python Flask to develop the backend server for the API.

So a modern-day API has four primary functions: GET, POST, PUT, and DELETE. GET retrieves data from a location on the web, POST inserts information, PUT updates a slice of data, and DELETE (you guessed it) gets rid of a given piece of information.

Below is a list of initial classes I’ve created and the functions for each one:

User 
- get
- post
- put
Account
- get
- post
- put
CreditCard
- get
- post
- put
Transaction
- get
- post
- put
AccountTypes
- get
CreditCardTypes
- get

Each class can have up to three different functions: Get, post, and put.* Classes User, Account, CreditCard, and Transaction have all three functions; that is because developers should be able to retrieve all the information about each class, add information, as well as modify it. For example, someone may want to create a new User (name: “Tommy Trojan”, id: 1234567890), or update a CreditCard (change current_balance from $20 to $3500, feels bad for that User). AccountTypes and CreditCardTypes, on the other hand, are just Credit Union provided information on the types of different products and services offered — if these were to change, it would not be the developer’s responsibility to change it, but rather the Credit Union’s.

But how exactly can things be “get”, “post”, and “put” on our server? And how does this relate to the SQLite database we made earlier?

Well, in SQL, when you want to retrieve data, you use SELECT. If you want to add data, you use INSERT. And if you want to change an item, you use UPDATE. Is it just a coincidence that each three of those actions sound like get, post, and put respectively?

And that is exactly what we do in each of our functions. For example, here’s a blueprint (pseudocode) for how to get, post, and put:

get(): 
db = connect_database()
query = db.execute_query("SELECT * FROM User")
return query.process_json()
post():
db = connect_database()
id = request_json["id"]
name = request_json["name"]
address = request_json["address"]
email = request_json["email"]
query = db.execute_query("INSERT into User(id, name, address, email) values (?,?,?,?), id, name, address, email)
return query.process_json()
put():
db = connect_database()
id = request_json["id"]
name = request_json["name"]
address = request_json["address"]
email = request_json["email"]
query = db.execute_query("UPDATE User SET id = ?, name = ?, address = ?, email = ?", id, name, addres, email)
return query.process_json()

Each time one of these functions is called, we connect to the database. That way, we can simply call SQL functions to get, add, and change data. We then retrieve that data and post-process it by converting it to JSON.

If you may recall, I wrote that for each Table, you may need more than one class. Well, based on the get functions stated above, there might be a justification for more than one. For most of the cases, get() simply selects every single element in the table with every attribute. But what if you only wanted the attributes for a User with a particular ID or an Account with a specific account number? In our current case, if we just called get in the User class, it would return all the attributes of all the users. Thus we create three more classes:

UserID
- get
AccountNumber
- get
CreditCardNumber
- get

Every time we would call the get for each of these classes, we would also have to provide a primary key to return attributes of a specific User, AccountNumber, or CreditCardNumber.

cURLing

So this will be the part where I partake in a sport that Canada dominates in every Winter Olympics.

Oh, how I wish.

cURL is the command line tool we will be using to test our API server and to ensure we can retrieve and set data on the database. Below is how you can use it to GET and POST information onto our server:

GET: 
curl -X GET --header "Accept: application/json" "<INSERT_SERVER_URL_HERE/(RESOURCE)>"
POST:

curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "<INSERT_FORMATTED_JSON_HERE>"<INSERT_SERVER_URL_HERE/(RESOURCE)>"

Here is an example of GETting the different AccountTypes from the server:

GET request

When a GET request is called, it calls the get function in our AccountTypes class, which then retrieves the data from the database and converts it to a readable JSON format.

Meanwhile, a POST of a new User to the server can be called with the appropriate JSON format:

POST request

In the POST command, you had to include the proper JSON format of the new User you would be adding to the SQL database. This insertion of the new user can be verified by getting that User based on the ID.

Conclusion

So there you have it! We have a basic API server up and running. Now all I have to do is debug, debug, debug, and … TEST. I need to make sure that each function runs correctly and the code is well-documented.

In Part 3, I’ll be discussing how to deploy an API server onto the cloud.

Image result for aws meme
Source: https://medium.com/konvergen/jenkins-for-node-js-app-on-aws-ec2-part-3-jenkins-node-js-app-integration-1fa9d1306d25

*: Delete is possible too, but we will handle that another time

--

--