Learn how to create a scalable full-stack application using Nuxt.js for the frontend and FastAPI for the backend with real-time features and optimized performance.
Architecture Overview
In today's fast-paced development environment, building applications that are both performant and scalable is crucial. Our application follows a modern microservices architecture with a clear separation between frontend and backend concerns.
The frontend is built with Nuxt.js, providing server-side rendering and excellent SEO capabilities, while the backend uses FastAPI for its high performance and automatic API documentation.
Key Features
- Real-time updates with WebSocket connections
- Server-side rendering for optimal SEO
- Automatic API documentation with Swagger UI
- JWT-based authentication system
- File upload and processing capabilities
- Database integration with PostgreSQL
Setting Up the Development Environment
Before we dive into the code, let's set up our development environment. We'll be using Docker to containerize our application for consistent development and deployment across different environments.
Pro Tip: Using Docker ensures that your development environment matches production, reducing deployment issues.
Frontend Implementation with Nuxt.js
Nuxt.js provides a robust framework for building Vue.js applications with built-in best practices. We'll leverage its file-based routing, auto-imports, and server-side rendering capabilities.
Code Examples
JavaScript Implementation
// Nuxt.js configuration
export default defineNuxtConfig({
ssr: true,
modules: [
'@nuxtjs/tailwindcss',
'@pinia/nuxt',
],
runtimeConfig: {
public: {
apiBase: process.env.API_BASE_URL || 'http://localhost:8000'
}
},
css: ['~/assets/css/main.css'],
build: {
transpile: ['@headlessui/vue']
}
})
// API integration with composables
export const useApi = () => {
const config = useRuntimeConfig()
const fetchData = async (endpoint) => {
const { data, error } = await useFetch(`${config.public.apiBase}${endpoint}`)
if (error.value) {
throw createError({
statusCode: error.value.statusCode,
statusMessage: error.value.statusMessage
})
}
return data.value
}
return { fetchData }
}Python Backend
# FastAPI main application
from fastapi import FastAPI, Depends, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from typing import List
from . import models, schemas, crud
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI(
title="Full Stack API",
description="Backend API for our full-stack application",
version="1.0.0"
)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/")
async def root():
return {"message": "Welcome to Full Stack API"}
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return itemsFrontend Structure
<!-- Nuxt.js layout component -->
<template>
<div class="min-h-screen bg-gray-50">
<header class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center">
<NuxtLink to="/" class="text-xl font-bold text-indigo-600">
FullStackApp
</NuxtLink>
</div>
<nav class="hidden md:flex space-x-8">
<NuxtLink
to="/"
class="text-gray-600 hover:text-indigo-600 transition-colors"
>
Home
</NuxtLink>
<NuxtLink
to="/dashboard"
class="text-gray-600 hover:text-indigo-600 transition-colors"
>
Dashboard
</NuxtLink>
</nav>
</div>
</div>
</header>
<main>
<slot />
</main>
</div>
</template>
<style scoped>
.router-link-active {
@apply text-indigo-600 font-medium;
}
</style>
