# Creating a REST API using Python Flask

Initially as a developer, I always thought there are only two aspects of a full stack application, you have the frontend, you straight up connect it to a database, fire queries and you're good to go.

As I kept learning more about backend technologies and what they offer, I understood the importance of database security, server-side abstraction, etc. 

## Prerequisites

1. Basic knowledge of Python
1. Python installed in your machine and a text editor (psst.., VS Code)

If I have a client side application, I can still directly connect it to a database, say using a MySQL driver in case of an SQL database. And yes, you could do that, it is completely possible. Which brings the question - 

## Why APIs?

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637399157040/nydiXeT6s.png)
When you connect your client-side application directly to a database, your database credentials and the raw queries you fire remain on the client-side, which could be seen by anyone since your application is running on a web browser. Not just that, in case of SQL for instance, running raw SQL queries from the client means that your application would be vulnerable to  [SQL injection](https://www.w3schools.com/sql/sql_injection.asp) . 

For further clarity on why you shouldn't be creating a direct connection to your database from the frontend, I'd suggest reading  [this](https://academind.com/tutorials/connect-to-database)  article from Academind.

## Flask

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637399191947/5p8X_0Y97.png)
Flask is a lightweight Python web framework which helps you to create basic web applications.

Flask is called a "micro" framework because it doesn't directly provide features like form validation, database abstraction, authentication, and so on.

Having said that, Flask is easy to setup, a lot less complex as compared to other frameworks.

## Setup

Create a new project folder and create a Python virtual environment inside of it.

```bash
mkdir sample-flask-app
cd ./sample-flask-app

# Linux
sudo apt-get install python3-venv    # If needed
python3 -m venv .venv
source .venv/bin/activate

# macOS
python3 -m venv .venv
source .venv/bin/activate

# Windows
py -3 -m venv .venv
# Use forward slashes if you are using Git Bash
.venv\scripts\activate
```

Update pip and install the modules *flask* and *python-dotenv*.

```bash
python -m pip install --upgrade pip
python -m pip install flask python-dotenv
```

Now, open this folder in your favorite text editor and create a new file ```app.py```.

## The Code

Let's get started with this simple hello-world app.

```python
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify({
        'greeting': 'Hello World!'
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug = True)
```
Taking a look at this code, it is rather simple, we create a new flask_app variable using the imported flask module. We then use this as a decorator to create a new route '/' (the default route) and write a function under it. We then return a greeting in JSON using the jsonify module.

## Environment Variables and Running the Dev Server

Before running the app, create a file ```.flaskenv``` and add the following -
```env
FLASK_ENV=development
```
This makes sure that the app runs with debug mode **on** so that the app restarts the server on every code change and you get a debugger on the browser in case of any errors.

You can run ```flask run``` on your command line to start this app.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637395793339/Iyu92GyKs.png)

As you can see, the debug mode is on and our dev server is running on port 5000. You can look this up in your browser. 
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637396089769/Ca4VWgUhA.png)

There you have it, you have your starter API set-up using Flask. 

## More Routes

You can go ahead and add more routes to the application, for demonstration I'll just go on and add my favorite games to display. 

```python
## games.py
games = [
    {"id": 1, "title": "Cyberpunk 2077",},
    {"id": 2, "title": "Horizon Zero Dawn",},
    {"id": 3, "title": "Battlefield V",}
]

```

I created a list of dictionaries in a new file ```games.py``` and I've imported it in ```app.py```.
Now, ```app.py``` looks like this - 

```python
from flask import Flask, jsonify
from games import games

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify({
        'greeting': 'Hello World!'
    })

@app.route('/games')
def all_games():
    return jsonify({
        'games': games,
    })

@app.route('/games/<game_id>')
def find_game_by_id(game_id):
    for game in games:
        if game["id"] == int(game_id):
            return jsonify({
                "game": game,
            })

```

I've added 2 functions for routes ```/games``` and ```/games/<game_id>```.
```/games``` simply returns the entire games list whereas the latter returns the dictionary with the key for 'id' mentioned in the query parameter. This parameter can be fetched in the route by using triangle-braces ```< and >``` or whatever you call them. 

Here are responses for these specific routes - 


> 
/games

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637398104389/fcDyV6PuU.png)


> 
/games/1


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637398192386/Am_3XEKX_.png)


There you have it, folks, we just wrote our first API using Python Flask. This is just the beginning. We can connect this app to a database for backend operations, but that is probably for a different thread. 

Thanks for reading, have a great day :)
