Phát triển API trên nền Flask cơ bản


1. Mục tiêu của bài viết

Bài viết này giúp mọi người tiếp cận với cách xây dựng một API, có thể áp dụng ngay, dành cho những người đã học lập trình với Python, có hiểu biết cơ bản về dòng lệnh và cách thức hoạt động của web.

2. Các định nghĩa

API là các phương thức, giao thức kết nối với các thư viện và ứng dụng khác. Nó là viết tắt của Application Programming Interface – giao diện lập trình ứng dụng. API cung cấp khả năng truy xuất dữ liệu thông qua internet, thường dùng kiểu dữ liệu JSON.

JSON là viết tắt của JavaScript Object Notation, là một kiểu định dạng dữ liệu tuân theo một quy luật nhất định mà hầu hết các ngôn ngữ lập trình hiện nay đều có thể đọc được. JSON là một tiêu chuẩn mở để trao đổi dữ liệu trên web.

Ví dụ về kiểu dữ liệu JSON:


3. Nền tảng được sử dụng

Trong phạm vi bài viết này, nền tảng được sử dụng là Flask - một thư viện phát triển web được xây dựng cho ngôn ngữ Python. Flask thực sự đơn giản để có thể xây dựng một ứng dụng, nó cũng được sử dụng trong một số trang web nổi tiếng như: Nexflix, Reddit, ...

Mình đang sử dụng IDE Pycharm 2019.3 + Python 3.6, các phiên bản đi kèm rất ổn định và tương thích với nhau. đảm bảo không xảy ra xung đột hay lỗi trong quá trình phát triển ứng dụng.


4. Một số phương thức thường sử dụng với HTTP

Có thể ngầm hiểu, các phương thức này là yều cầu của chúng ta đối với dữ liệu. Một số phương thức được mình liệt kê dưới đây thường được sử dụng:

GET: phương thức GET thường được dùng để gửi dữ liệu lên server với một tham số cụ thể, hay có thể gọi là truy xuất dữ liệu với tốc độ cao.

Ví dụ về phương thức GET:

Khi ta gửi yêu cầu đọc nhiệt độ từ cảm biến DTH 11 thông qua server:
nguyentrieuphong.com/iot-stations/
chúng ta có thể gửi lệnh như sau:
nguyentrieuphong.com/iot-stations/home.php?read=temperature
Kết quả sẽ trả về giá trị nhiệt độ dưới kiểu dữ liệu JSON.

POST: phương thức GET thường được dùng để gửi dữ liệu lên server với nội dung bảo mật hơn phương thức GET, có thể gửi nhiều dạng dữ liệu hơn nhưng tốc độ thấp.

Ví dụ về phương thức POST:

@app.route('/post/', methods=['POST'])
def post_something():
param = request.form.get('temperature')
print(temprature)
if temperature:
return jsonify({
"Temperature": f"Nhiệt độ hiện tại là {temperature} độ C",
"METHOD" : "POST"
})
else:
return jsonify({
"ERROR": "Kiểm tra kết nối!"
})

Ngoài ra trong HTTP còn một số phương thức khác như là: PUT, PATCH, DELETE, ... các bạn có thể tìm hiểu thêm tại đây


5. Bắt đầu xây dựng API

Chúng ta sẽ phải tạo project folder cho tiện quản lý, vào ổ đĩa D và tạo thư mục mới với tên "api". Khởi động Pycharm và mở thư mục api ra. Sau đó, cài đặt virtual environment (môi trường làm việc ảo) vào thư mục này thông qua project interpreter mọi người sẽ thấy thư mục venv được tạo ra trong thư mục api nếu thành công.


6. Cài đặt các thư viện

Như đã đề cập ở trên, chúng ta sẽ sử dụng Flask, một thư viện Python tối giản để xây dựng các ứng dụng web. Chúng tôi sẽ sử dụng lệnh pip để cài đặt Flask.

Mở terminal trong Pycharm, xác định đang ở trong virtual environment bằng cách xem có dòng (venv) trước địa chỉ dẫn tới thư mục api hay không, nếu có thì đúng (nếu không có thì việc cài thư viện có vấn đề, cần quay lại bước 5). Từ Terminal, nhập lệnh:

pip install flask

Sau khi cài đặt xong gói Flask, chúng ta tạo file api.py và nhập đoạn code sau đây vào:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
return {'hello': 'trieuphong'}

app.run()

Chạy thử ta được kết quả là một địa chỉ local tại http://127.0.0.1:5000/ hãy truy cập vào đây để kiểm tra, dữ liệu trả về dạng thô như sau:
{"hello":"trieuphong"}
Dữ liệu chúng ta nhận được chính là định dạng JSON, bây giờ chúng ta sẽ mở rộng nó ra một chút.


7. Tạo dữ liệu Shopee

Phần tiếp theo, chúng ta sẽ thử tạo API quản lý hàng hoá trong một shop trên trang TMDT Shopee. Đầu tiên, hãy xác định các nhãn dữ liệu cần thiết.

Name,
Brand,
Available,
Price.

Trên đây là dữ liệu sẽ xác định mỗi loại hàng hoá. Chúng ta có thể tạo một danh sách Python để giúp lưu trữ từng thông tin về những hàng hoá này.

store = [
{
"name" : "L298N",
"brand" : "Nshop",
"available" : 20,
"price" : "40.000"
},
{
"name": "Arduino Uno",
"brand": "Hshop",
"available": 16,
"price": "90.000"
}
]

Phía trên là danh sách kiểu thư viện, chúng ta sẽ sử dụng danh sách này để tìm hiểu các phương thức khác trong chương trình sau đây. (thư viện jsonify được thêm vào)

from flask import Flask, jsonify
app = Flask(__name__)

store = [
{
"name" : "L298N",
"brand" : "Nshop",
"available" : 20,
"price" : "40.000"
},
{
"name": "Arduino Uno",
"brand": "Hshop",
"available": 16,
"price": "90.000"
}
]

@app.route('/store')
def get_store():
return jsonify(store)

app.run()

Với @app.route('/store') chúng ta chạy chương trình, truy cập vào địa chỉ http://127.0.0.1:5000/store và kiểm tra kết quả, dữ liệu trả về dạng thô như sau:

[
{"available":20,"brand":"Nshop","name":"L298N","price":"40.000"},
{"available":16,"brand":"Hshop","name":"Arduino Uno","price":"90.000"}
]


8. Truy xuất hàng hoá

Chúng ta hãy thử tạo ra một endpoint khác với chức năng truy xuất hàng hoá trong thư viện như sau:

from flask import Flask, jsonify
app = Flask(__name__)

store = [
{
"name" : "L298N",
"brand" : "Nshop",
"available" : 20,
"price" : "40.000"
},
{
"name": "Arduino Uno",
"brand": "Hshop",
"available": 16,
"price": "90.000"
}
]

@app.route('/store')
def get_store():
return jsonify(store)

@app.route('/store/<int:index>')
def get_product(index):
product = store[index]
return jsonify(product)

app.run()

Với  @app.route('/store/<int:imdex>') chúng ta chạy chương trình, sau đó truy cập vào địa chỉ sau đây: http://127.0.0.1:5000/store/x với x là số thứ tự của các hàng hoá có trong thư viện để truy xuất dữ liệu của từng loại hàng hoá.


9. Thêm vào dữ liệu mới

Bằng phương thức POST đã đề cập ở trên, bây giờ chúng ta sẽ tạo một endpoint cho phép thêm vào dữ liệu hàng hoá mới. (thư viện request được thêm vào)

from flask import Flask, jsonify, request
app = Flask(__name__)

store = [
{
"name" : "L298N",
"brand" : "Nshop",
"available" : 20,
"price" : "40.000"
},
{
"name": "Arduino Uno",
"brand": "Hshop",
"available": 16,
"price": "90.000"
}
]

@app.route('/store')
def get_store():
return jsonify(store)

@app.route('/store/<int:index>')
def get_product(index):
product = store[index]
return jsonify(product)

@app.route('/store', methods = ['POST'])
def add_product():
product = request.get_json()
store.append(product)
return {'id' : len(store)}, 200

app.run()

Trên postman, tiến hành gửi dữ liệu JSON với phương thức POST. Kết quả trả về là ID của dữ liệu mới và code trạng thái 200 cho thấy dữ liệu đã được thêm vào thành công như sau:


Kiểm tra lại với phương thức GET, chúng ta thấy dữ liệu với đã được thêm vào.


10. Cập nhật và xoá

Phương thức cập nhật PUT và xoá DELETE tương tự như trên, dữ liệu được cập nhật và xoá thông qua ID của dữ liệu.

from flask import Flask, jsonify, request
app = Flask(__name__)

store = [
{
"name" : "L298N",
"brand" : "Nshop",
"available" : 20,
"price" : "40.000"
},
{
"name": "Arduino Uno",
"brand": "Hshop",
"available": 16,
"price": "90.000"
}
]

@app.route('/store')
def get_store():
return jsonify(store)

@app.route('/store/<int:index>')
def get_product(index):
product = store[index]
return jsonify(product)

@app.route('/store', methods = ['POST'])
def add_product():
product = request.get_json()
store.append(product)
return {'id' : len(store)}, 200

@app.route('/store/<int:index>', methods = ['PUT'])
def update(index):
update_product = request.get_json()
store[index] = update_product
return jsonify(store[index])

@app.route('/store/<int:index>', methods = ['DELETE'])
def delete_product(index):
deleted = store.pop(index)
return jsonify(deleted), 200

app.run()

Trên postman, sử dụng phương thức DELETE với ID = 1, kết quả trả về là dữ liệu đã xoá và code trạng thái 200 báo đã xoá thành công.



Kiểm tra lại với phương thức GET (ID = 1), ta thấy kết quả trả về lỗi 500 vì dữ liệu đã mất đi ID = 1, như sau:


Đó là tất cả những gì của bài viết này, hy vọng bài viết mang lại cho bạn trải nghiệm tuyệt vời về cách xây dựng API trên nền Flask. Chúng ta sẽ tiếp tục tìm hiểu về cách thức xây dựng API trong các bài viết tiếp theo. Chúc mọi người ngủ ngon.