@kodeme-io/next-core-client
v0.8.4
Published
Backend-agnostic client interfaces for next-core with caching, retry, and performance monitoring
Maintainers
Readme
@kodeme-io/next-core-client
Backend-agnostic client interfaces for next-core.
Overview
This package provides generic interfaces that enable next-core to work with any backend:
- ✅ Odoo (JSON-RPC) - Current
- ✅ FastAPI (REST) - Future
- ✅ GraphQL - Future
- ✅ Custom backends - Anytime
Core Interfaces
IDataClient
Generic interface for data operations (CRUD, search, etc.):
import { IDataClient, SearchParams } from '@kodeme-io/next-core-client'
// Works with ANY backend implementing IDataClient
const partners = await dataClient.searchRead({
model: 'res.partner',
filters: [
{ field: 'is_company', operator: 'eq', value: true }
],
fields: ['id', 'name', 'email'],
limit: 20
})IAuthClient
Generic interface for authentication:
import { IAuthClient } from '@kodeme-io/next-core-client'
// Works with ANY backend implementing IAuthClient
const result = await authClient.login('user', 'password')
console.log(result.user.name)
const isValid = await authClient.checkSession()Implementations
Odoo Adapter
npm install @kodeme-io/next-core-odoo-apiimport { OdooAdapter } from '@kodeme-io/next-core-odoo-api'
const client = new OdooAdapter({
url: 'https://odoo.example.com',
database: 'production'
})
// Implements both IDataClient and IAuthClientFastAPI Adapter (Future)
npm install @kodeme-io/next-core-fastapi-apiimport { FastAPIAdapter } from '@kodeme-io/next-core-fastapi-api'
const client = new FastAPIAdapter({
url: 'https://api.example.com'
})
// Same interface, different backend!Usage
1. Choose Backend
// app/lib/backend-client.ts
import { OdooAdapter } from '@kodeme-io/next-core-odoo-api'
// import { FastAPIAdapter } from '@kodeme-io/next-core-fastapi-api'
// Switch backend via env variable
const BACKEND = process.env.NEXT_PUBLIC_BACKEND || 'odoo'
export const dataClient = BACKEND === 'odoo'
? new OdooAdapter({
url: process.env.NEXT_PUBLIC_ODOO_URL!,
database: process.env.NEXT_PUBLIC_ODOO_DB!,
})
: new FastAPIAdapter({
url: process.env.NEXT_PUBLIC_API_URL!,
})2. Use in Components
// app/components/PartnerList.tsx
import { dataClient } from '@/lib/backend-client'
export function PartnerList() {
const [partners, setPartners] = useState([])
useEffect(() => {
// Works with both Odoo and FastAPI!
dataClient.searchRead({
model: 'res.partner',
filters: [{ field: 'is_company', operator: 'eq', value: true }],
fields: ['id', 'name', 'email'],
}).then(setPartners)
}, [])
return <ul>{partners.map(p => <li key={p.id}>{p.name}</li>)}</ul>
}3. Switching Backends
Just change environment variable:
# .env (Odoo)
NEXT_PUBLIC_BACKEND=odoo
NEXT_PUBLIC_ODOO_URL=https://odoo.example.com
NEXT_PUBLIC_ODOO_DB=production
# .env (FastAPI)
NEXT_PUBLIC_BACKEND=fastapi
NEXT_PUBLIC_API_URL=https://api.example.comNo code changes needed! 🎉
Generic Types
Filters
import type { Filter } from '@kodeme-io/next-core-client'
const filters: Filter[] = [
{ field: 'name', operator: 'like', value: 'John%' },
{ field: 'age', operator: 'gte', value: 18 },
{ field: 'country', operator: 'in', value: ['US', 'UK', 'CA'] }
]Complex Filters
import type { FilterGroup } from '@kodeme-io/next-core-client'
const complexFilters: FilterGroup = {
operator: 'AND',
conditions: [
{ field: 'is_company', operator: 'eq', value: true },
{
operator: 'OR',
conditions: [
{ field: 'country', operator: 'eq', value: 'US' },
{ field: 'country', operator: 'eq', value: 'UK' }
]
}
]
}Pagination
const { data, pagination } = await client.searchPaginated({
model: 'res.partner',
limit: 20,
offset: 0
})
console.log(pagination.total) // Total records
console.log(pagination.hasMore) // More records available?Creating Custom Adapters
Implement IDataClient and/or IAuthClient:
import {
IDataClient,
IAuthClient,
SearchParams,
AuthResult
} from '@kodeme-io/next-core-client'
export class MyCustomAdapter implements IDataClient, IAuthClient {
async searchRead<T>(params: SearchParams): Promise<T[]> {
// Convert generic params to your backend's format
const response = await fetch(`/api/${params.model}`, {
method: 'POST',
body: JSON.stringify({
filters: params.filters,
limit: params.limit
})
})
return response.json()
}
async login(username: string, password: string): Promise<AuthResult> {
const response = await fetch('/auth/login', {
method: 'POST',
body: JSON.stringify({ username, password })
})
const data = await response.json()
return {
userId: data.id,
sessionId: data.token,
user: data.user
}
}
// ... implement other methods
}Benefits
- Backend Flexibility - Switch backends without changing app code
- Type Safety - Full TypeScript support
- Future Proof - Easy to add new backends
- Testable - Mock adapters for testing
- Clean Architecture - Separation of concerns
License
MIT © ABC Food Development Team
