Basic App Example

Learn how to build a simple application with Query-2jz, including models, queries, and basic CRUD operations.

Project Setup

Set up a basic Query-2jz application with a simple data model.

Initialize Project

# Create new project
mkdir my-query-2jz-app
cd my-query-2jz-app

# Initialize package.json
npm init -y

# Install Query-2jz
npm install query-2jz

# Install development dependencies
npm install -D @types/node typescript ts-node

Project Structure

my-query-2jz-app/
├── src/
│   ├── models/
│   │   └── User.ts
│   ├── config/
│   │   └── query-2jz.config.ts
│   └── index.ts
├── package.json
├── tsconfig.json
└── README.md

Define Models

Create a simple User model with basic fields and relationships.

User Model

// src/models/User.ts
export interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
  posts?: Post[];
}

export interface Post {
  id: string;
  title: string;
  content: string;
  authorId: string;
  publishedAt?: Date;
  createdAt: Date;
  updatedAt: Date;
  author?: User;
}

export interface CreateUserInput {
  name: string;
  email: string;
  age?: number;
  isActive?: boolean;
}

export interface UpdateUserInput {
  name?: string;
  email?: string;
  age?: number;
  isActive?: boolean;
}

Query-2jz Configuration

// src/config/query-2jz.config.ts
import { Query-2jzConfig } from 'query-2jz';

export const query-2jzConfig: Query-2jzConfig = {
  database: {
    type: 'sqlite',
    connection: './database.sqlite'
  },
  models: [
    {
      name: 'User',
      fields: {
        id: { type: 'id' },
        name: { type: 'string', required: true },
        email: { type: 'email', required: true, unique: true },
        age: { type: 'number' },
        isActive: { type: 'boolean', default: true },
        createdAt: { type: 'date', default: 'now' },
        updatedAt: { type: 'date', default: 'now' },
        posts: { 
          type: 'relation', 
          model: 'Post', 
          many: true,
          foreignKey: 'authorId'
        }
      },
      indexes: ['email', 'isActive']
    },
    {
      name: 'Post',
      fields: {
        id: { type: 'id' },
        title: { type: 'string', required: true },
        content: { type: 'string', required: true },
        authorId: { type: 'string', required: true },
        publishedAt: { type: 'date' },
        createdAt: { type: 'date', default: 'now' },
        updatedAt: { type: 'date', default: 'now' },
        author: { 
          type: 'relation', 
          model: 'User',
          foreignKey: 'authorId'
        }
      },
      indexes: ['authorId', 'publishedAt']
    }
  ]
};

Application Code

Create the main application file with basic CRUD operations.

Main Application

// src/index.ts
import { Query-2jz } from 'query-2jz';
import { query-2jzConfig } from './config/query-2jz.config';
import { CreateUserInput, UpdateUserInput } from './models/User';

async function main() {
  // Initialize Query-2jz
  const query-2jz = new Query-2jz(query-2jzConfig);
  
  try {
    // Create a new user
    console.log('Creating user...');
    const newUser = await query-2jz.create({
      model: 'User',
      data: {
        name: 'John Doe',
        email: 'john@example.com',
        age: 30,
        isActive: true
      }
    });
    console.log('Created user:', newUser);

    // Find user by ID
    console.log('Finding user by ID...');
    const user = await query-2jz.query({
      model: 'User',
      where: { id: newUser.id }
    });
    console.log('Found user:', user.data[0]);

    // Update user
    console.log('Updating user...');
    const updatedUser = await query-2jz.update({
      model: 'User',
      id: newUser.id,
      data: {
        name: 'John Updated',
        age: 31
      }
    });
    console.log('Updated user:', updatedUser);

    // Find all active users
    console.log('Finding all active users...');
    const activeUsers = await query-2jz.query({
      model: 'User',
      where: { isActive: true },
      orderBy: 'createdAt:desc',
      limit: 10
    });
    console.log('Active users:', activeUsers.data);

    // Create a post for the user
    console.log('Creating post...');
    const newPost = await query-2jz.create({
      model: 'Post',
      data: {
        title: 'My First Post',
        content: 'This is my first post using Query-2jz!',
        authorId: newUser.id,
        publishedAt: new Date()
      }
    });
    console.log('Created post:', newPost);

    // Find user with posts
    console.log('Finding user with posts...');
    const userWithPosts = await query-2jz.query({
      model: 'User',
      where: { id: newUser.id },
      include: ['posts']
    });
    console.log('User with posts:', userWithPosts.data[0]);

    // Find posts with author
    console.log('Finding posts with author...');
    const postsWithAuthor = await query-2jz.query({
      model: 'Post',
      include: ['author'],
      orderBy: 'publishedAt:desc'
    });
    console.log('Posts with author:', postsWithAuthor.data);

  } catch (error) {
    console.error('Error:', error);
  } finally {
    // Close database connection
    await query-2jz.close();
  }
}

// Run the application
main().catch(console.error);

Package Configuration

Configure your package.json and TypeScript for the project.

package.json

{
  "name": "my-query-2jz-app",
  "version": "1.0.0",
  "description": "A basic Query-2jz application",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "query-2jz": "^1.0.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0",
    "ts-node": "^10.0.0"
  },
  "keywords": ["query-2jz", "database", "api"],
  "author": "Your Name",
  "license": "MIT"
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Running the Application

Learn how to run and test your basic Query-2jz application.

Development Mode

# Run in development mode
npm run dev

# Output:
# Creating user...
# Created user: { id: '1', name: 'John Doe', email: 'john@example.com', ... }
# Finding user by ID...
# Found user: { id: '1', name: 'John Doe', email: 'john@example.com', ... }
# Updating user...
# Updated user: { id: '1', name: 'John Updated', email: 'john@example.com', ... }
# Finding all active users...
# Active users: [{ id: '1', name: 'John Updated', email: 'john@example.com', ... }]
# Creating post...
# Created post: { id: '1', title: 'My First Post', content: '...', ... }
# Finding user with posts...
# User with posts: { id: '1', name: 'John Updated', posts: [...] }
# Finding posts with author...
# Posts with author: [{ id: '1', title: 'My First Post', author: {...} }]

Production Build

# Build the application
npm run build

# Run the built application
npm start

Next Steps

Explore more advanced features and examples.

Advanced Features

  • • Add authentication and authorization
  • • Implement real-time subscriptions
  • • Add caching for better performance
  • • Create a web API with Express.js
  • • Add data validation and error handling
  • • Implement pagination and filtering
  • • Add logging and monitoring

Best Practices

Do

  • • Use TypeScript for type safety
  • • Define clear model relationships
  • • Implement proper error handling
  • • Use environment variables for configuration
  • • Add proper logging
  • • Write tests for your code
  • • Use version control

Don't

  • • Skip error handling
  • • Hardcode configuration values
  • • Ignore type safety
  • • Skip testing
  • • Ignore logging
  • • Skip version control
  • • Ignore best practices