Adaptive API Quick Start
This guide walks through deploying a complete Library API using the Adaptive API Gateway.
Overview
We’ll build a Library API that manages books and borrowing operations through six steps:
-
Create OpenAPI specification
-
Deploy spec to Kubernetes
-
Test auto-generated endpoints
-
Create custom Python handler
-
Deploy handler to Kubernetes
-
Test custom endpoints with real business logic
Step 1: Create OpenAPI Spec
Create an OpenAPI 3.0 specification defining your API:
cat > /tmp/library-api.openapi.yaml <<'EOF'
openapi: 3.0.3
info:
title: Library API
description: API for managing library books and borrowing operations
version: 1.0.0
servers:
- url: /api/adaptive/library-api
description: SDL environment
tags:
- name: Books
description: Book catalog management
paths:
/books:
get:
tags:
- Books
summary: List all books
operationId: listBooks
parameters:
- name: available
in: query
required: false
schema:
type: boolean
responses:
'200':
description: Successful response
content:
application/json:
example:
books:
- id: 1
title: "The Python Handbook"
author: "Jane Developer"
isbn: "978-1234567890"
available: true
count: 1
post:
tags:
- Books
summary: Add a new book
operationId: createBook
requestBody:
required: true
content:
application/json:
example:
title: "New Book"
author: "Author Name"
isbn: "978-1234567890"
responses:
'201':
description: Book created successfully
content:
application/json:
example:
id: 2
title: "New Book"
author: "Author Name"
isbn: "978-1234567890"
available: true
/books/{bookId}:
get:
tags:
- Books
summary: Get book by ID
operationId: getBook
parameters:
- name: bookId
in: path
required: true
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
example:
id: 1
title: "The Python Handbook"
author: "Jane Developer"
isbn: "978-1234567890"
available: true
'404':
description: Book not found
EOF
Step 2: Deploy OpenAPI Spec
Add your spec to the ConfigMap and deploy:
# Get existing specs to preserve them
kubectl get configmap df-adaptive-api-sample-specs -n svraft \
-o jsonpath='{.data.sample-crud\.openapi\.yaml}' > /tmp/sample-crud.openapi.yaml
# Update ConfigMap with both specs
kubectl create configmap df-adaptive-api-sample-specs \
--from-file=sample-crud.openapi.yaml=/tmp/sample-crud.openapi.yaml \
--from-file=library-api.openapi.yaml=/tmp/library-api.openapi.yaml \
-n svraft --dry-run=client -o yaml | kubectl apply -f -
# Restart deployment
kubectl rollout restart deployment df-adaptive-api -n svraft
# Wait for pod to be ready
kubectl wait --for=condition=ready pod -l app=df-adaptive-api -n svraft --timeout=60s
Step 3: Test Auto-Generated Endpoints
Test the endpoints that auto-generate responses from the OpenAPI spec:
# List all books (returns example data from spec)
curl -u username:password https://localhost/api/adaptive/library-api/books
# Get a specific book
curl -u username:password https://localhost/api/adaptive/library-api/books/1
# Create a book (echoes request with example data)
curl -u username:password -X POST https://localhost/api/adaptive/library-api/books \
-H "Content-Type: application/json" \
-d '{"title":"New Book","author":"Author Name","isbn":"978-1234567890"}'
{
"books": [
{
"id": 1,
"title": "The Python Handbook",
"author": "Jane Developer",
"isbn": "978-1234567890",
"available": true,
"publishedYear": 2024,
"addedAt": "2024-01-15T10:00:00Z"
},
{
"id": 2,
"title": "FastAPI Patterns",
"author": "John Coder",
"isbn": "978-0987654321",
"available": true,
"publishedYear": 2023,
"addedAt": "2023-06-20T14:30:00Z"
}
],
"count": 2,
"timestamp": "2025-11-26T14:00:00Z"
}
At this stage, all endpoints return the example data defined in your OpenAPI spec. No Python code required yet.
Step 4: Create Custom Handler
Write a Python FastAPI handler with real business logic:
cat > /tmp/library-api_handler.py <<'EOF'
"""
Library API Custom Handler - Real business logic implementation
"""
from fastapi import APIRouter, HTTPException, Query, Request
from datetime import datetime
from typing import Optional, Dict
router = APIRouter(tags=["Library API"])
# In-memory storage (replace with database in production)
books_db: Dict[int, dict] = {
1: {
"id": 1,
"title": "The Python Handbook",
"author": "Jane Developer",
"isbn": "978-1234567890",
"available": True,
"publishedYear": 2024
}
}
next_book_id = 2
@router.get("/books")
async def list_books(
available: Optional[bool] = Query(None)
):
"""List all books with optional filtering"""
books = list(books_db.values())
if available is not None:
books = [b for b in books if b["available"] == available]
return {"books": books, "count": len(books)}
@router.post("/books")
async def create_book(request: Request):
"""Add a new book to the catalog"""
global next_book_id
body = await request.json()
if "title" not in body or "author" not in body:
raise HTTPException(status_code=400, detail="Title and author required")
new_book = {
"id": next_book_id,
"title": body["title"],
"author": body["author"],
"isbn": body.get("isbn", f"AUTO-{next_book_id}"),
"available": True,
"publishedYear": body.get("publishedYear", datetime.utcnow().year)
}
books_db[next_book_id] = new_book
next_book_id += 1
return new_book
@router.get("/books/{bookId}")
async def get_book(bookId: int):
"""Get a specific book by ID"""
if bookId not in books_db:
raise HTTPException(status_code=404, detail=f"Book {bookId} not found")
return books_db[bookId]
EOF
Step 5: Deploy Custom Handler
Before deploying the handler, remove the OpenAPI spec to avoid route conflicts:
# Remove library-api spec (keep sample-crud)
kubectl get configmap df-adaptive-api-sample-specs -n svraft \
-o jsonpath='{.data.sample-crud\.openapi\.yaml}' > /tmp/sample-crud.openapi.yaml
kubectl create configmap df-adaptive-api-sample-specs \
--from-file=sample-crud.openapi.yaml=/tmp/sample-crud.openapi.yaml \
-n svraft --dry-run=client -o yaml | kubectl apply -f -
# Deploy custom handler
kubectl create configmap df-adaptive-api-handlers \
--from-file=library-api_handler.py=/tmp/library-api_handler.py \
-n svraft --dry-run=client -o yaml | kubectl apply -f -
# Restart deployment
kubectl rollout restart deployment df-adaptive-api -n svraft
# Wait for pod to be ready
kubectl wait --for=condition=ready pod -l app=df-adaptive-api -n svraft --timeout=60s
Step 6: Test Custom Endpoints
Test the real business logic:
# List books (returns real data from in-memory storage)
curl -u username:password https://localhost/api/adaptive/library-api/books
# Add a new book (actually creates it)
curl -u username:password -X POST https://localhost/api/adaptive/library-api/books \
-H "Content-Type: application/json" \
-d '{"title":"Docker Deep Dive","author":"Mike Container","isbn":"978-5566778899"}'
# Verify it was added
curl -u username:password https://localhost/api/adaptive/library-api/books
# Get the new book by ID
curl -u username:password https://localhost/api/adaptive/library-api/books/2
The handler now maintains real state with business logic validation.
Advanced Topics
Multiple Handlers
You can deploy multiple handlers in the same ConfigMap:
kubectl create configmap df-adaptive-api-handlers \
--from-file=library-api_handler.py=/tmp/library-api_handler.py \
--from-file=weather_handler.py=/tmp/weather_handler.py \
--from-file=products_handler.py=/tmp/products_handler.py \
-n svraft --dry-run=client -o yaml | kubectl apply -f -
Each handler will be mounted at its own path.
Custom Endpoints Not in Spec
Handlers can add endpoints not defined in the OpenAPI spec:
@router.get("/stats")
async def get_stats():
"""Custom endpoint - not in OpenAPI spec"""
return {"total_books": len(books_db)}
These will automatically appear in the Swagger UI.
Database Integration
For production use, replace in-memory storage with database access:
import psycopg2
from os import getenv
DB_HOST = getenv("DB_HOST", "df-backend-postgresql")
DB_NAME = getenv("DB_NAME", "datafabric")
@router.get("/books")
async def list_books():
conn = psycopg2.connect(host=DB_HOST, database=DB_NAME, ...)
cursor = conn.cursor()
cursor.execute("SELECT * FROM books")
# ... process results
Additional Resources
-
Application code: https://github.com/raft-tech/rdp/tree/main/sdl-adaptive-api
-
Helm chart:
~/rdp/charts/sdl-adaptive-api -
Complete example: See
EXAMPLE.mdin application repository