UNPKG

nextjs-django-client

Version:

A comprehensive, type-safe SDK for seamlessly integrating Next.js 15+ applications with Django REST Framework backends

522 lines (401 loc) โ€ข 13.4 kB
# Next.js Django Client SDK ๐Ÿš€ **The easiest way to connect your Next.js app to Django REST Framework** A comprehensive, type-safe SDK that makes integrating Next.js applications with Django backends simple and powerful. Perfect for beginners and experts alike! ## โœจ Why Choose This SDK? - ๐ŸŽฏ **Beginner-Friendly**: Get started in minutes with our step-by-step guide - ๐Ÿ”’ **Secure by Default**: Built-in JWT authentication and CSRF protection - ๐Ÿ“ **Full TypeScript**: Complete type safety for your API calls - ๐Ÿค– **Auto-Generated Code**: Generate API clients from your OpenAPI specs - โšก **Modern React**: Built for Next.js 15+ with React 18+ hooks - ๐Ÿงช **Well Tested**: Comprehensive test suite with 95%+ coverage ## ๐Ÿš€ Quick Start (5 minutes) ### Step 1: Install the Package ```bash npm install nextjs-django-client # or yarn add nextjs-django-client # or pnpm add nextjs-django-client ``` #### Bundle Options Choose the right bundle for your needs: ```typescript // Full bundle (258 KB) - All features included import { createDjangoApiClient, useAuth, useRBAC } from 'nextjs-django-client'; // Core bundle (136 KB) - Basic features only (recommended for most users) import { createDjangoApiClient, useAuth } from 'nextjs-django-client/core'; // Advanced bundle (171 KB) - RBAC, social login, advanced auth import { useRBAC, useSocialLogin, AdvancedAuthProvider } from 'nextjs-django-client/advanced'; ``` ### Step 2: Create Your API Client Create a new file `lib/api.ts` in your Next.js project: ```typescript import { createDjangoApiClient } from 'nextjs-django-client'; // Replace with your Django API URL export const apiClient = createDjangoApiClient('http://localhost:8000/api'); ``` ### Step 3: Add Authentication (Optional) Wrap your app with the AuthProvider in `app/layout.tsx` or `pages/_app.tsx`: ```tsx import { AuthProvider } from 'nextjs-django-client'; import { apiClient } from '@/lib/api'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> <AuthProvider apiClient={apiClient}> {children} </AuthProvider> </body> </html> ); } ### Step 4: Start Making API Calls Now you can use the API client anywhere in your app: ```tsx 'use client'; // For Next.js 13+ App Router import { useState, useEffect } from 'react'; import { apiClient } from '@/lib/api'; interface User { id: number; email: string; name: string; } export default function UsersPage() { const [users, setUsers] = useState<User[]>([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchUsers() { try { const response = await apiClient.get<User[]>('/users/'); setUsers(response); } catch (error) { console.error('Failed to fetch users:', error); } finally { setLoading(false); } } fetchUsers(); }, []); if (loading) return <div>Loading...</div>; return ( <div> <h1>Users</h1> <ul> {users.map(user => ( <li key={user.id}>{user.name} ({user.email})</li> ))} </ul> </div> ); } ``` ## ๐Ÿ” Authentication Made Easy ### Simple Login Form ```tsx 'use client'; import { useAuth } from 'nextjs-django-client'; export default function LoginForm() { const { login, isLoading, error } = useAuth(); const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.currentTarget); await login({ email: formData.get('email') as string, password: formData.get('password') as string, }); }; return ( <form onSubmit={handleSubmit} className="space-y-4"> <div> <label htmlFor="email">Email:</label> <input id="email" name="email" type="email" required className="border rounded px-3 py-2" /> </div> <div> <label htmlFor="password">Password:</label> <input id="password" name="password" type="password" required className="border rounded px-3 py-2" /> </div> {error && <p className="text-red-500">{error.message}</p>} <button type="submit" disabled={isLoading} className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50" > {isLoading ? 'Logging in...' : 'Login'} </button> </form> ); } ``` ### Protected Routes ```tsx 'use client'; import { useAuth } from 'nextjs-django-client'; import { useRouter } from 'next/navigation'; import { useEffect } from 'react'; export default function ProtectedPage() { const { user, isLoading, error } = useAuth(); // error property available for error handling const router = useRouter(); useEffect(() => { if (!isLoading && !user) { router.push('/login'); } }, [user, isLoading, router]); if (isLoading) return <div>Loading...</div>; if (!user) return null; return ( <div> <h1>Welcome, {user.name}!</h1> <p>This is a protected page.</p> </div> ); } ``` ## ๐Ÿค– Auto-Generate Your API Client (Recommended!) The easiest way to get started is by generating your API client from your Django OpenAPI schema. This gives you: - โœ… **100% Type Safety**: All your API endpoints are fully typed - โœ… **Auto-completion**: Your IDE knows all available methods and parameters - โœ… **Always Up-to-date**: Regenerate when your API changes - โœ… **Zero Boilerplate**: No manual API client code to write ### Step 1: Export Your Django OpenAPI Schema First, make sure your Django project exports an OpenAPI schema. Add this to your Django `urls.py`: ```python # urls.py from django.contrib import admin from django.urls import path, include from rest_framework.schemas import get_schema_view urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('your_app.urls')), # Add this line to export your schema path('api/schema/', get_schema_view( title="Your API", description="API for your awesome project", version="1.0.0" ), name='openapi-schema'), ] ``` ### Step 2: Generate Your API Client ```bash # Download your schema (replace with your URL) curl http://localhost:8000/api/schema/ > openapi.json # Generate your API client npx nextjs-django-codegen generate -i openapi.json -o src/generated ``` ### Step 3: Use Your Generated Client ```tsx // src/generated/index.ts is automatically created import { GeneratedApiClient, useGetUsers, useCreateUser } from '@/generated'; // Create your client instance const client = new GeneratedApiClient('http://localhost:8000/api'); // Use in React components with generated hooks export default function UsersPage() { const { data: users, isLoading, error } = useGetUsers(); const createUser = useCreateUser(); const handleCreateUser = async () => { await createUser.mutateAsync({ name: 'John Doe', email: 'john@example.com' }); }; if (isLoading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; return ( <div> <h1>Users</h1> <button onClick={handleCreateUser}>Add User</button> <ul> {users?.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> </div> ); } ``` ### Configuration File (Optional) Create `openapi.config.js` for custom settings: ```javascript module.exports = { input: './openapi.json', output: './src/generated', generateTypes: true, generateClient: true, generateHooks: true, clientName: 'GeneratedApiClient', // Default changed to avoid naming conflicts prettier: true, }; ``` ## ๐Ÿ“š Manual Configuration (Advanced) If you prefer manual setup or need custom configuration: ### Authentication Configuration ```typescript import { configureAuth } from 'nextjs-django-client'; const authConfig = configureAuth({ loginEndpoint: '/api/auth/login/', refreshEndpoint: '/api/auth/refresh/', userEndpoint: '/api/auth/user/', useEmailAsUsername: true, secureTokens: true, }); ``` ### API Client Configuration ```typescript import { createApiClient } from 'nextjs-django-client'; const apiClient = createApiClient({ baseURL: 'https://api.example.com', timeout: 30000, defaultHeaders: { 'Content-Type': 'application/json', }, retries: 3, retryDelay: 1000, }); ``` ## TypeScript Support The SDK is built with TypeScript-first approach: ```typescript interface CustomUser extends User { customField: string; } // Type-safe authentication const { user } = useAuth<CustomUser>(); // Type-safe API calls const response = await apiClient.get<CustomUser[]>('/users/'); ``` ## ๐Ÿš€ Production Ready ### Bundle Optimization Choose the right bundle for your needs to minimize bundle size: - **Core Bundle** (136 KB): Basic HTTP client, authentication, and OpenAPI generation - **Advanced Bundle** (171 KB): RBAC, social login, and advanced authentication features - **Full Bundle** (259 KB): All features included ### Browser Compatibility - โœ… **No Node.js dependencies** in browser bundles - โœ… **Tree-shakeable** exports for optimal bundle size - โœ… **ES2022+ target** for modern browsers - โœ… **Separate CLI bundle** with Node.js dependencies ## Testing ```bash # Run tests npm test # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch ``` ## Development ```bash # Install dependencies npm install # Start development build npm run dev # Run linting npm run lint # Format code npm run format # Type checking npm run type-check ``` ## Project Structure ``` src/ โ”œโ”€โ”€ auth/ # Authentication system โ”‚ โ”œโ”€โ”€ providers/ # React context providers โ”‚ โ”œโ”€โ”€ hooks/ # Authentication hooks โ”‚ โ”œโ”€โ”€ types/ # TypeScript types โ”‚ โ””โ”€โ”€ utils/ # Auth utilities โ”œโ”€โ”€ client/ # HTTP client โ”‚ โ”œโ”€โ”€ http/ # Core HTTP client โ”‚ โ”œโ”€โ”€ interceptors/ # Request/response interceptors โ”‚ โ””โ”€โ”€ types/ # HTTP client types โ”œโ”€โ”€ state/ # State management (coming soon) โ”œโ”€โ”€ hooks/ # React hooks โ”œโ”€โ”€ utils/ # Utility functions โ””โ”€โ”€ types/ # Global TypeScript types ``` ## Roadmap ### Sprint 2 (Weeks 3-4) - JWT auto-refresh mechanism - Enhanced `useAuth` hook with auto-refresh - Secure cookie handling improvements ### Sprint 3 (Weeks 5-6) - Customizable authentication endpoints - Role-based access control (RBAC) - Social login providers ### Sprint 4 (Weeks 7-8) - Advanced state management with optimistic updates - Tag-based cache invalidation - Batch mutations ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes with tests 4. Ensure all tests pass and coverage is maintained 5. Submit a pull request ## ๐Ÿšจ Troubleshooting ### Common Issues and Solutions #### 1. CORS Errors ```python # In your Django settings.py CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", # Your Next.js dev server "https://yourdomain.com", # Your production domain ] CORS_ALLOW_CREDENTIALS = True ``` #### 2. Authentication Token Issues ```typescript // Check if token is being sent apiClient.addInterceptor({ request: (config) => { console.log('Headers:', config.headers); return config; } }); ``` #### 3. TypeScript Errors with Generated Code ```bash # Regenerate your API client npx nextjs-django-codegen generate -i openapi.json -o src/generated # Make sure your OpenAPI schema is valid npx nextjs-django-codegen validate -i openapi.json ``` #### 4. Network Errors in Development ```typescript // Use the correct Django dev server URL const apiClient = createDjangoApiClient('http://127.0.0.1:8000/api'); // Not localhost if you're having issues ``` ### Getting Help - ๐Ÿ“– **Documentation**: Check our [full documentation](docs/) - ๐Ÿ› **Bug Reports**: [Open an issue](https://github.com/taqiudeen275/nextjs-django-client/issues) - ๐Ÿ’ฌ **Questions**: [Start a discussion](https://github.com/taqiudeen275/nextjs-django-client/discussions) - ๐Ÿ“ง **Email**: support@nextjs-django-client.com ## ๐Ÿค Contributing We love contributions! Here's how you can help: 1. **Fork the repository** 2. **Create a feature branch**: `git checkout -b feature/amazing-feature` 3. **Make your changes** and add tests 4. **Run tests**: `npm test` 5. **Submit a pull request** See our [Contributing Guide](CONTRIBUTING.md) for detailed instructions. ## ๐Ÿ“„ License MIT License - see [LICENSE](LICENSE) file for details. --- **Made with โค๏ธ for the Django + Next.js community**