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:

bash
# 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:

text
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:

properties
# 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:

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

bash
# 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:

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:

dart
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:

bash
# 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:

bash
# 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:

properties
# 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:

bash
# Build for production
khadem build

# This creates a production-ready bundle

Deploy the Build

Extract and run the production build:

bash
# 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

bash
# Start development server
khadem serve

# Run with custom port
khadem serve --port 3000

# Run in background
khadem serve --background

Database

bash
# 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:

bash
# 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:

bash
# 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:

🎯 Project Checklist

Project created with khadem new
Dependencies installed with dart pub get
Environment configured in .env
First endpoint created and tested
Server running on http://localhost:8080

On this page