@eyjs/http-server
v1.0.0
Published
Server package for EyJS framework with Elysia integration
Maintainers
Readme
@eyjs/http-server
HTTP server package for the EyJS framework with Elysia integration. Provides decorator-based routing, middleware support, and seamless integration with EyJS applications.
Features
- 🚀 Elysia Integration - Built on top of the fast Elysia web framework
- 🎯 Decorator-Based Routing - Simple
@Controller()and@Get(),@Post()decorators - 🔧 TypeScript Support - Full TypeScript definitions and type safety
- ⚡ EyJS Integration - Works seamlessly with EyJS dependency injection
- 📝 Swagger Documentation - Automatic API documentation generation
- 🌐 CORS Support - Built-in CORS middleware
- 🛡️ Middleware Support - Flexible middleware system
Installation
# Using Bun (recommended)
bun add @eyjs/http-server
# Using npm
npm install @eyjs/http-server
# Using yarn
yarn add @eyjs/http-server
# Using pnpm
pnpm add @eyjs/http-serverPrerequisites
This package requires:
@eyjs/core@^1.0.4- EyJS core framework
Quick Start
1. Basic Server Setup
import { EyJs } from '@eyjs/core'
import { Controller, Get, Post } from '@eyjs/http-server'
@Controller('/api')
export class ApiController {
@Get('/hello')
async getHello() {
return { message: 'Hello from EyJS!' }
}
@Post('/users')
async createUser(data: { name: string; email: string }) {
return {
id: '123',
...data,
createdAt: new Date()
}
}
}
// Start the server
const app = await EyJs.start(import.meta.url)2. Advanced Controller
import { Controller, Get, Post, Put, Delete, Param, Body } from '@eyjs/http-server'
import { Injectable } from '@eyjs/core'
@Controller('/users')
@Injectable()
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async getUsers() {
return await this.userService.findAll()
}
@Get('/:id')
async getUser(@Param('id') id: string) {
return await this.userService.findById(id)
}
@Post()
async createUser(@Body() data: CreateUserDto) {
return await this.userService.create(data)
}
@Put('/:id')
async updateUser(
@Param('id') id: string,
@Body() data: UpdateUserDto
) {
return await this.userService.update(id, data)
}
@Delete('/:id')
async deleteUser(@Param('id') id: string) {
await this.userService.delete(id)
return { message: 'User deleted successfully' }
}
}API Reference
Decorators
@Controller(path?)
Defines a controller class with optional base path.
@Controller('/api/v1') // All routes will be prefixed with /api/v1
export class ApiController {
// Controller methods
}HTTP Method Decorators
@Get(path?)- Handle GET requests@Post(path?)- Handle POST requests@Put(path?)- Handle PUT requests@Delete(path?)- Handle DELETE requests@Patch(path?)- Handle PATCH requests
Parameter Decorators
@Param(name)- Extract route parameters@Body()- Extract request body@Query(name?)- Extract query parameters@Headers(name?)- Extract headers
Server Configuration
import { EyJsServer } from '@eyjs/http-server'
const server = new EyJsServer({
port: 3000,
hostname: '0.0.0.0',
cors: {
origin: ['http://localhost:3000'],
credentials: true
},
swagger: {
documentation: {
info: {
title: 'My API',
version: '1.0.0',
description: 'API Documentation'
}
}
}
})Usage Examples
Basic CRUD Controller
import { Controller, Get, Post, Put, Delete, Param, Body } from '@eyjs/http-server'
import { Injectable } from '@eyjs/core'
interface User {
id: string
name: string
email: string
}
interface CreateUserDto {
name: string
email: string
}
interface UpdateUserDto {
name?: string
email?: string
}
@Controller('/users')
@Injectable()
export class UserController {
private users: User[] = []
@Get()
async getUsers(): Promise<User[]> {
return this.users
}
@Get('/:id')
async getUser(@Param('id') id: string): Promise<User | null> {
return this.users.find(user => user.id === id) || null
}
@Post()
async createUser(@Body() data: CreateUserDto): Promise<User> {
const user: User = {
id: Math.random().toString(36).substr(2, 9),
...data
}
this.users.push(user)
return user
}
@Put('/:id')
async updateUser(
@Param('id') id: string,
@Body() data: UpdateUserDto
): Promise<User | null> {
const userIndex = this.users.findIndex(user => user.id === id)
if (userIndex === -1) return null
this.users[userIndex] = { ...this.users[userIndex], ...data }
return this.users[userIndex]
}
@Delete('/:id')
async deleteUser(@Param('id') id: string): Promise<{ message: string }> {
const userIndex = this.users.findIndex(user => user.id === id)
if (userIndex === -1) {
return { message: 'User not found' }
}
this.users.splice(userIndex, 1)
return { message: 'User deleted successfully' }
}
}Query Parameters and Headers
import { Controller, Get, Query, Headers } from '@eyjs/http-server'
@Controller('/search')
export class SearchController {
@Get()
async search(
@Query('q') query: string,
@Query('page') page: number = 1,
@Query('limit') limit: number = 10,
@Headers('user-agent') userAgent?: string
) {
return {
query,
page,
limit,
userAgent,
results: []
}
}
}Error Handling
import { Controller, Get, Param } from '@eyjs/http-server'
import { ErrorCodes } from '@eyjs/shared-errors'
@Controller('/users')
export class UserController {
@Get('/:id')
async getUser(@Param('id') id: string) {
const user = await this.userService.findById(id)
if (!user) {
throw new Error(ErrorCodes.USER_NOT_FOUND)
}
return user
}
}Middleware Integration
import { Controller, Get, Use } from '@eyjs/http-server'
import { UseAuth } from '@eyjs/auth'
@Controller('/protected')
export class ProtectedController {
@Get('/data')
@UseAuth()
async getProtectedData() {
return { message: 'This is protected data' }
}
@Get('/admin')
@UseAuth({ roles: ['admin'] })
async getAdminData() {
return { message: 'Admin only data' }
}
}File Upload
import { Controller, Post, Body } from '@eyjs/http-server'
@Controller('/upload')
export class UploadController {
@Post()
async uploadFile(@Body() file: File) {
// Handle file upload
return {
filename: file.name,
size: file.size,
type: file.type
}
}
}WebSocket Support
import { Controller, Get, WebSocket } from '@eyjs/http-server'
@Controller('/ws')
export class WebSocketController {
@Get('/chat')
@WebSocket()
async chat(ws: WebSocket) {
ws.on('message', (message) => {
// Handle incoming messages
ws.send(`Echo: ${message}`)
})
}
}Configuration
Server Options
import { EyJsServer } from '@eyjs/http-server'
const server = new EyJsServer({
port: 3000,
hostname: '0.0.0.0',
cors: {
origin: true,
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
},
swagger: {
documentation: {
info: {
title: 'EyJS API',
version: '1.0.0',
description: 'EyJS Framework API Documentation'
},
servers: [
{
url: 'http://localhost:3000',
description: 'Development server'
}
]
}
},
logger: {
level: 'info'
}
})Environment Configuration
# Server configuration
PORT=3000
HOSTNAME=0.0.0.0
NODE_ENV=development
# CORS configuration
CORS_ORIGIN=http://localhost:3000
CORS_CREDENTIALS=true
# Swagger configuration
SWAGGER_TITLE=EyJS API
SWAGGER_VERSION=1.0.0Advanced Usage
Custom Middleware
import { Controller, Get, Use } from '@eyjs/http-server'
function loggingMiddleware() {
return async (request: any, next: () => Promise<any>) => {
console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`)
return await next()
}
}
@Controller('/api')
export class ApiController {
@Get('/test')
@Use(loggingMiddleware())
async test() {
return { message: 'Test endpoint' }
}
}Response Transformation
import { Controller, Get } from '@eyjs/http-server'
@Controller('/api')
export class ApiController {
@Get('/users')
async getUsers() {
const users = await this.userService.findAll()
return {
success: true,
data: users,
meta: {
count: users.length,
timestamp: new Date().toISOString()
}
}
}
}Pagination Support
import { Controller, Get, Query } from '@eyjs/http-server'
@Controller('/api')
export class ApiController {
@Get('/users')
async getUsers(
@Query('page') page: number = 1,
@Query('limit') limit: number = 10
) {
const offset = (page - 1) * limit
const [users, total] = await Promise.all([
this.userService.findMany({ offset, limit }),
this.userService.count()
])
return {
data: users,
pagination: {
page,
limit,
total,
pages: Math.ceil(total / limit)
}
}
}
}Testing
Unit Tests
import { describe, it, expect } from 'bun:test'
import { EyJsServer } from '@eyjs/http-server'
describe('HTTP Server', () => {
it('should start server', async () => {
const server = new EyJsServer({ port: 0 })
await server.start()
expect(server.isRunning()).toBe(true)
await server.stop()
})
})Integration Tests
import { describe, it, expect } from 'bun:test'
describe('API Endpoints', () => {
it('should return hello message', async () => {
const response = await fetch('http://localhost:3000/api/hello')
const data = await response.json()
expect(data.message).toBe('Hello from EyJS!')
})
})Performance
Optimization Tips
- Enable Compression
const server = new EyJsServer({
compression: true
})- Use Connection Pooling
const server = new EyJsServer({
keepAlive: true,
keepAliveTimeout: 5000
})- Enable HTTP/2
const server = new EyJsServer({
http2: true
})Troubleshooting
Common Issues
1. "Port already in use" error
- Check if another process is using the port
- Use a different port number
- Kill the process using the port
2. CORS errors
- Configure CORS properly in server options
- Check allowed origins and methods
- Ensure credentials are handled correctly
3. Route not found errors
- Verify controller decorators are correct
- Check route paths and parameters
- Ensure controllers are registered with EyJS
Debug Mode
Enable debug logging:
DEBUG=eyjs:http-serverContributing
Contributions are welcome! Please read our Contributing Guide for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
