DEV Community

Raffy Castillo
Raffy Castillo

Posted on

FastAPI: A Python Web Framework for NodeJS Developers

FastAPI: A Python Web Framework for NodeJS Developers

By Raffy Castillo

Introduction

My journey with FastAPI started with the same skepticism most Node.js developers have about learning new frameworks. But here's what got me excited: FastAPI comes pre-packaged with everything we painstakingly add to Express.js. No more adding express-validator for data checks, no more setting up swagger-ui-express for API docs, no more crafting error handling middleware. It's all there.

What really clicked for me was how FastAPI just works. FastAPI isn't just trying to replicate Express.js in Python. It's a modern framework built for today's development challenges.

So what makes FastAPI stand out? It comes loaded with features that would normally require multiple npm packages in Express. The speed matches and sometimes surpasses Express.js performance. It catches errors before they hit production, and your API documentation stays current automatically. No more maintaining separate docs that inevitably get out of sync with your code.

Why should you consider FastAPI?

  • Built-in Features: What takes multiple npm packages in Express comes ready to use in FastAPI
  • Speed: Just as fast as Express.js, sometimes even faster!
  • Error Prevention: Catches common API errors before your code runs (like when someone sends text where a number should be)
  • Auto Documentation: Your API docs stay up-to-date automatically: no more maintaining separate documentation

Core Features and Syntax

Basic Setup

Let me walk you through creating your first API. If you're like me and have built Express servers before, this will feel familiar yet refreshingly different. We'll create a simple endpoint that sends back some JSON data:

Express.js:

// This is like your typical app.js or server.js file const express = require('express'); const app = express(); app.use(express.json()); // To handle JSON requests const port = 3000; app.get('/', (req, res) => { res.json({ message: "Hello, World!" }); }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); }); 
Enter fullscreen mode Exit fullscreen mode

FastAPI:

# This is your main.py file from fastapi import FastAPI import uvicorn app = FastAPI() @app.get("/") def read_root(): return {"message": "Hello, World!"} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) 
Enter fullscreen mode Exit fullscreen mode

Save this as main.py and run it. Just like how you visit http://localhost:3000 in Express, you'll visit http://localhost:8000 here. The cool part? Remember all those times you had to manually document your API endpoints or set up Swagger? Just visit http://localhost:8000/docs after running your FastAPI server. You'll find your API documentation automatically generated. You don't get that in Express!

Request Handling and Path Parameters

Here's where FastAPI really shines. Remember those tedious validation checks we write in Express? The ones where we meticulously verify if an ID is actually a number, or if a request body contains all required fields? Let me show you how FastAPI handles this elegantly:

Express.js:

// In Express, you need to validate data yourself app.get('/products/:id', (req, res) => { const productId = req.params.id; // You'd probably add validation like this: if (isNaN(productId)) { return res.status(400).json({ error: "Product ID must be a number" }); } // Then handle the request res.json({ productId: Number(productId), name: "Sample Product", price: 29.99 }); }); app.post('/products', (req, res) => { const { name, price } = req.body; // Manual validation - you often see this in Express if (!name || typeof name !== 'string') { return res.status(400).json({ error: "Name is required and must be text" }); } if (!price || typeof price !== 'number') { return res.status(400).json({ error: "Price is required and must be a number" }); } res.json({ message: "Product created!", product: { name, price } }); }); 
Enter fullscreen mode Exit fullscreen mode

FastAPI:

from fastapi import FastAPI, HTTPException from pydantic import BaseModel app = FastAPI() # This is like creating a schema for your data class Product(BaseModel): name: str price: float @app.get("/products/{product_id}") def get_product(product_id: int): # FastAPI handles the number validation automatically!  return { "product_id": product_id, "name": "Sample Product", "price": 29.99 } @app.post("/products") def create_product(product: Product): # FastAPI validates the JSON automatically!  return { "message": "Product created!", "product": product } 
Enter fullscreen mode Exit fullscreen mode

Notice how FastAPI handles all the validation automatically? A lot of trivial checks are already baked into it! When someone sends invalid data (like text where a number should be), FastAPI will automatically send back a helpful error message.

Async Support

The async story in FastAPI feels like coming home for a Node.js developer. Remember how natural it felt the first time you used async/await in Express? FastAPI brings that same elegance to Python. Let's pretend that we are building endpoints for a typical e-commerce site:

Express.js:

// Imagine this function gets orders from a database const getOrdersFromDB = async (userId) => { // Simulate database delay await new Promise(resolve => setTimeout(resolve, 100)); return [ { id: 1, item: "Laptop" }, { id: 2, item: "Mouse" } ]; }; app.get('/users/:userId/orders', async (req, res) => { try { const userId = req.params.userId; const orders = await getOrdersFromDB(userId); res.json({ userId, orders }); } catch (error) { res.status(500).json({ error: "Could not fetch orders", details: error.message }); } }); 
Enter fullscreen mode Exit fullscreen mode

FastAPI:

async def get_orders_from_db(user_id: int): # Simulate database delay  import asyncio await asyncio.sleep(0.1) return [ {"id": 1, "item": "Laptop"}, {"id": 2, "item": "Mouse"} ] @app.get("/users/{user_id}/orders") async def get_user_orders(user_id: int): try: orders = await get_orders_from_db(user_id) return {"user_id": user_id, "orders": orders} except Exception as e: raise HTTPException( status_code=500, detail="Could not fetch orders" ) 
Enter fullscreen mode Exit fullscreen mode

Both frameworks handle async operations in a similar way. If you're comfortable with async/await in JavaScript, you'll feel right at home with FastAPI's async support!

Compare and Contrast

FastAPI vs Express.js

  1. Type System

    • Express.js: Relies on TypeScript for type safety (optional)
    • FastAPI: Built-in type validation with Pydantic
  2. Documentation

    • Express.js: Manual documentation or third-party tools
    • FastAPI: Automatic interactive API documentation
  3. Performance

    • Express.js: Known for its speed and lightweight nature
    • FastAPI: One of the fastest Python frameworks, comparable to Node.js
  4. Middleware

    • Express.js: Uses .use() for middleware
    • FastAPI: Uses "dependencies" and middleware with more structured approach
  5. Learning Curve

    • Express.js: Minimal, very flexible but requires more boilerplate
    • FastAPI: Slightly steeper due to Python typing, but more features out of the box

Tips for Learning FastAPI as a Node.js Developer

I want to share some insights from my own transition from Node.js to FastAPI. These are the things I wish someone had told me when I started:

  1. Embrace Python Types
    Don't fight the type system. It's actually trying to help you catch bugs before they happen. Coming from JavaScript, I was initially resistant to all the type hints, but it makes a whole lot more sense when you think of all the hours you could potentially saved by catching small mistakes before committing to them.

  2. The Async World is Different, But Better
    Python's async ecosystem might feel a bit strange at first. Where's the event loop? Why can't I use await everywhere? But once you understand the "async all the way down" principle, you'll appreciate how Python handles concurrency.

  3. Your Development Environment Matters

 # Here's my go-to setup that's never failed me python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # The essentials you'll need pip install fastapi uvicorn 
Enter fullscreen mode Exit fullscreen mode
  1. Key Resources That Helped Me

Here's what I've learned: FastAPI isn't just Express with Python syntax. It's what happens when you take everything we love about Express, add modern features we wish we had out of the box, and wrap it all in a framework that catches our mistakes before they become problems.

Top comments (1)

Collapse
 
devops_fundamental profile image
DevOps Fundamental

This was such a well-written and thoughtful post—I really enjoyed the way you explained your ideas and offered a fresh perspective. Looking forward to reading more from you!