Membuat REST API Sederhana dengan FastAPI
🚀 Membuat REST API Sederhana dengan FastAPI
Saya telah membuat REST API menggunakan FastAPI, sebuah framework modern berbasis Python yang cepat dan ringan.
🎯 Tujuan API
- Menyediakan endpoint GET yang mengembalikan data statis
- Menyediakan endpoint GET dengan parameter dinamis (path)
- Menyediakan endpoint POST untuk menerima data JSON
Buat API untuk database Classimodel
classicmodels adalah contoh database MySQL populer yang sering digunakan untuk belajar SQL. Di dalamnya ada tabel-tabel seperti:
- customers
- orders
- employees
- products
- offices
- productlines
dan satu table user untuk JWT nantinya
🛠️ Setup Environment
Buat environment virtual terlebih dahulu:
1
2
3
python -m venv venv #buat environment
.\venv\Scripts\activate #aktifkan env
pip install fastapi uvicorn sqlalchemy pymysql #install library
Struktur Folder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
classicmodels-api/
├── main.py
├── models
├── customers.py
├── orders.py
├── employees.py
├── offices.py
├── products.py
├── productlines.py
├── users.py
├── schemas
├── customers.py
├── orders.py
├── employees.py
├── offices.py
├── products.py
├── productlines.py
├── token.py
├── crud
├── customers.py
├── orders.py
├── employees.py
├── offices.py
├── products.py
├── productlines.py
├── auth.py
Models
models digunakan untuk:
Mewakili struktur tabel di database.
Dibuat dengan SQLAlchemy.
Digunakan untuk membaca, menulis, dan query ke database.
Salah satu contoh dalam kode membuat model dalam membuat satu tabel sekaligus relasi dengan tabel lainnya
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String, Integer, Float, ForeignKey
from database import Base
class Product(Base):
__tablename__ = "products"
productCode = Column(String(15), primary_key=True, index=True)
productName = Column(String(70))
productLine = Column(String(50), ForeignKey("productlines.productLine"))
productScale = Column(String(10))
productVendor = Column(String(50))
productDescription = Column(String)
quantityInStock = Column(Integer)
buyPrice = Column(Float)
MSRP = Column(Float)
productLine_rel = relationship("ProductLines", back_populates="products")
Schemas
schemas digunakan untuk:
Menentukan bentuk data yang masuk dan keluar melalui API.
Dibuat dengan Pydantic.
Tidak berhubungan langsung dengan database, hanya untuk validasi dan serialisasi data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pydantic import BaseModel
class ProductBase(BaseModel):
productName: str
productLine: str
productScale: str
productVendor: str
productDescription: str
quantityInStock: int
buyPrice: float
MSRP: float
class ProductCreate(ProductBase):
productCode: str # Required saat create
class ProductUpdate(ProductBase):
pass # productCode tidak perlu diupdate
class ProductSimple(ProductCreate):
class Config:
orm_mode = True
class Product(ProductSimple):
class Config:
orm_mode = True
CRUD
CRUD menghubungkan antara database (models) dan input/output API (schemas), menggunakan SQLAlchemy ORM. Terdapat juga fungsi CRUD tiap file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from sqlalchemy.orm import Session
from models.products import Product
from schemas.products import ProductCreate, ProductUpdate
def get_all_products(db: Session):
return db.query(Product).all()
def get_product_by_code(db: Session, productCode: str):
return db.query(Product).filter(Product.productCode == productCode).first()
def create_product(db: Session, product: ProductCreate):
db_product = Product(**product.dict())
db.add(db_product)
db.commit()
db.refresh(db_product)
return db_product
def update_product(db: Session, productCode: str, product: ProductUpdate):
db_product = db.query(Product).filter(Product.productCode == productCode).first()
if db_product:
for key, value in product.dict().items():
setattr(db_product, key, value)
db.commit()
db.refresh(db_product)
return db_product
def delete_product(db: Session, productCode: str):
db_product = db.query(Product).filter(Product.productCode == productCode).first()
if db_product:
db.delete(db_product)
db.commit()
return db_product
🎯 Fungsi Utama main.py
Setup FastAPI App Menginisialisasi aplikasi FastAPI dan konfigurasi CORS agar bisa diakses dari frontend mana pun.
Autentikasi Login (JWT)
- Simulasi login user (
fake_users_db) - Membuat token JWT jika login berhasil
- Token berisi
sub(username) dan waktu kedaluwarsa - Token digunakan untuk mengakses endpoint yang dilindungi
- Simulasi login user (
Verifikasi Token
- Setiap endpoint yang butuh login menggunakan
Depends(get_current_user) - Fungsi ini mengecek token yang dikirim dari header Authorization
- Setiap endpoint yang butuh login menggunakan
Dependency Database
get_db()mengelola koneksi database menggunakan SQLAlchemy
Endpoint
/login- Menerima username dan password
- Jika valid, membalas dengan token JWT (
access_token)
Endpoint
/productsdan berbagai table lainnya- Endpoint yang dilindungi token JWT
- Hanya bisa diakses oleh user yang sudah login
- Mengambil semua data produk dari database menggunakan
product_crud.get_all_products(db)
🧠 Singkatnya: File main.py ini mengatur login, membuat dan mengecek token JWT, serta melindungi endpoint /products agar hanya bisa diakses oleh user yang sudah login.
Lengkapnya di repository GitHub.
