Creating Your First Project
Learn how to create, configure, and run your first Khadem backend project. This guide walks you through the entire process from project creation to your first API endpoint.
Prerequisites
Make sure you have Khadem CLI installed before proceeding
Create a New Project
Use the Khadem CLI to generate a new project with all the necessary files and folders:
# Create a new Khadem project
khadem new --name=my_first_api
# Navigate into the project directory
cd my_first_api
# Install project dependencies
dart pub get
# Start the development server
khadem serve
What happens: The CLI creates a complete project structure with all necessary files, dependencies, and configurations.
Project Structure Overview
Khadem projects follow a clean, organized structure inspired by Laravel:
my_first_api/
├── lib/
│ ├── main.dart # Application entry point
│ ├── app/
│ │ ├── http/
│ │ │ ├── controllers/
│ │ │ │ └── home_controller.dart
│ │ │ └── middleware/
│ │ │ └── cors_middleware.dart
│ │ ├── jobs/
│ │ ├── listeners/
│ │ ├── models/
│ │ └── providers/
│ │ ├── app_service_provider.dart
│ │ ├── event_service_provider.dart
│ │ └── scheduler_service_provider.dart
│ ├── bin/ # CLI commands and utilities
│ ├── config/
│ │ └── app.dart # Application configuration
│ ├── core/
│ │ └── kernel.dart # Application kernel
│ ├── database/
│ │ ├── migrations/
│ │ └── seeders/
│ └── routes/
│ ├── socket.dart
│ └── web.dart
├── config/
│ ├── development/
│ │ └── logging.json
│ └── production/
│ └── logging.json
├── lang/
│ ├── ar/
│ └── en/
├── public/
│ └── assets/
├── resources/
│ └── views/
├── storage/
│ └── logs/
├── tests/
├── .env
├── .gitignore
├── pubspec.yaml
└── pubspec.lock
📁 Key Directories
- lib/app/ - Application logic and business code
- lib/core/ - Application kernel and bootstrap
- lib/database/ - Migrations and seeders
- config/ - Environment-specific configurations
- lib/routes/ - HTTP and WebSocket route definitions
📄 Key Files
- lib/main.dart - Application entry point
- lib/config/app.dart - Application configuration
- pubspec.yaml - Project dependencies
- .env - Environment variables
- lib/core/kernel.dart - Service registration
Environment Configuration
Configure your application environment variables in the .env
file:
# Application Configuration
APP_NAME=MyFirstAPI
APP_ENV=development
APP_PORT=8080
APP_LOCALE=en
# Database Configuration (MySQL)
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=my_first_api_db
DB_USERNAME=root
DB_PASSWORD=
# JWT Authentication
JWT_SECRET="your-super-secret-jwt-key-here"
JWT_ACCESS_EXPIRY_MINUTES=60
JWT_REFRESH_EXPIRY_DAYS=30
Configuration Files
The main configuration is handled in config/app.dart
:
// lib/config/app.dart
import 'package:khadem/khadem.dart';
class AppConfig {
static final env = Khadem.env;
static Map<String, Map<String, dynamic>> get configs => {
'database': {
'driver': env.getOrDefault('DB_CONNECTION', 'mysql'),
'host': env.getOrDefault('DB_HOST', 'localhost'),
'port': env.getInt('DB_PORT'),
'database': env.get('DB_DATABASE'),
'username': env.get('DB_USERNAME'),
'password': env.get('DB_PASSWORD'),
},
};
}
Creating Your First Endpoint
Let's create a simple API endpoint. First, create a controller:
Create Home Controller
# Create the controllers directory if it doesn't exist
mkdir -p app/http/controllers
# Create the home controller file
touch app/http/controllers/home_controller.dart
Add the controller logic in lib/app/http/controllers/home_controller.dart
:
import 'package:khadem/khadem_dart.dart';
class HomeController {
static Future<void> index(Request req, Response res) async {
res.sendJson({
'message': 'Welcome to Khadem API!',
'status': 'success',
'timestamp': DateTime.now().toIso8601String(),
'version': '1.0.0'
});
}
static Future<void> welcome(Request req, Response res) async {
final name = req.query('name') ?? 'Guest';
res.sendJson({
'message': 'Hello, ${name}! Welcome to your first Khadem API.',
'status': 'success',
'data': {
'name': name,
'user_agent': req.headers['user-agent'],
'ip': req.ip,
}
});
}
static Stream<String> stream(Request req, Response res) async* {
res.setContentType('text/plain');
for (int i = 1; i <= 10; i++) {
yield 'Chunk ${i}: ${DateTime.now()}\n';
await Future.delayed(Duration(seconds: 1));
}
}
}
Register Routes
Update routes/web.dart
to register your routes:
import 'package:khadem/khadem_dart.dart';
import '../lib/app/http/controllers/home_controller.dart';
import '../lib/core/kernel.dart';
void registerRoutes(Server server) {
// Register global middlewares
server.useMiddlewares(Kernel.middlewares);
// Home Routes
server.group(
prefix: '/api',
middleware: [],
routes: (router) async {
router.get('/hello', HomeController.index);
router.get('/welcome', HomeController.welcome);
router.get('/stream', HomeController.stream);
},
);
// Serve static files
server.serveStatic();
}
Running in Development
Start the development server with hot reload:
# Run the application in development mode
khadem serve
Server URLs:
• HTTP Server: http://localhost:8080
• WebSocket Server: ws://localhost:8080
Test Your API
Test your first endpoint:
# Test your first endpoint
curl http://localhost:8080/api/hello
# Test with query parameter
curl "http://localhost:8080/api/welcome?name=World"
# Test streaming endpoint
curl http://localhost:8080/api/stream
Database Setup (Optional)
If you want to use a database, update your .env
file with database credentials:
# Update these values for your database
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=my_first_api_db
DB_USERNAME=root
DB_PASSWORD=your_password_here
Khadem supports MySQL out of the box. PostgreSQL, SQLite, and MongoDB support is coming soon.
Building for Production
Create an optimized production build:
# Build for production
khadem build
# This creates a production-ready bundle
Deploy the Build
Extract and run the production build:
# Extract the production build
tar -xzf build/server.tar.gz -C build/
# Run the production server
dart run ./build/server/bin/server.jit
Useful CLI Commands
Development
# Start development server
khadem serve
# Run with custom port
khadem serve --port 3000
# Run in background
khadem serve --background
Database
# Run database migrations
khadem migrate
# Create a new migration
khadem make:migration create_users_table
# Run database seeders
khadem seed
Common Issues & Solutions
❌ Port Already in Use
If port 8080 is busy:
# Kill process using port 8080
lsof -ti:8080 | xargs kill -9
# Or use a different port
khadem serve --port 3000
⚠️ Dependencies Issues
If you encounter dependency issues:
# Clean and reinstall dependencies
rm -rf .dart_tool pubspec.lock
dart pub get
# Update Khadem to latest version
dart pub global activate khadem
Next Steps
Your Khadem project is ready! Continue exploring:
Routing & Controllers
Learn about HTTP routing and controllers
Configuration
Environment and app configuration
Models & Database
Working with data models and ORM
Service Container
Dependency injection and providers
🎯 Project Checklist
khadem new
dart pub get
.env
http://localhost:8080