Post

Membuat REST API Sederhana dengan FastAPI

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

  1. Setup FastAPI App Menginisialisasi aplikasi FastAPI dan konfigurasi CORS agar bisa diakses dari frontend mana pun.

  2. 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
  3. Verifikasi Token

    • Setiap endpoint yang butuh login menggunakan Depends(get_current_user)
    • Fungsi ini mengecek token yang dikirim dari header Authorization
  4. Dependency Database

    • get_db() mengelola koneksi database menggunakan SQLAlchemy
  5. Endpoint /login

    • Menerima username dan password
    • Jika valid, membalas dengan token JWT (access_token)
  6. Endpoint /products dan 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.

This post is licensed under CC BY 4.0 by the author.