This is a high-performance, zero-reflection Kotlin/Java library for connecting to Odoo via the ODXProxy Gateway. It uses Kotlinx Serialization and OkHttp internally but exposes a Static Facade for consumers.
Core Principles:
- Entry Point: Always use
io.odxproxy.OdxProxy. Do not instantiateOdxProxyClientmanually. - Async Model: All operations return
java.util.concurrent.CompletableFuture<T>. - Thread Safety: Serialization and Network calls are offloaded to background threads automatically.
- Strict Typing: Odoo's polymorphic JSON is handled via specific wrapper types (
OdxMany2One,OdxVariant).
The AI must strictly use these types to prevent serialization crashes caused by Odoo's inconsistent JSON (e.g., returning false instead of null).
| Type | Use Case | Behavior |
|---|---|---|
OdxMany2One |
Relational fields (many2one) |
Handles [id, "Name"], false, or null. Provides .id (Int?) and .name (String?). |
OdxVariant<T> |
Nullable fields (e.g., string, date) |
Handles cases where Odoo returns false (boolean) instead of null or the expected type. |
OdxClientKeywordRequest |
Pagination & Options | Handles limit, offset, order, fields, and context. |
Must be called once before usage.
// Kotlin
val instance = OdxInstanceInfo("https://odoo.my-server.com", 1, "my-db", "odoo-api-key")
val config = OdxProxyClientInfo(instance, "odx-proxy-key", "https://gateway.odxproxy.io")
OdxProxy.init(config)Always use @Serializable
@Serializable
data class Partner(
val id: Int,
val name: String,
@SerialName("company_id") val company: OdxMany2One, // Handles [1, "MyCompany"] or false
val email: OdxVariant<String> // Handles "mail@test.com" or false
)Use OdxProxy.searchRead or OdxProxy.read
val keywords = OdxClientKeywordRequest(
fields = listOf("name", "email", "company_id"),
limit = 10,
order = "id desc"
)
// Returns CompletableFuture<OdxServerResponse<List<Partner>>>
OdxProxy.searchRead(
model = "res.partner",
params = listOf(listOf("customer_rank", ">", 0)), // Domain
keyword = keywords,
id = null, // Auto-generate Request ID
resultType = Partner::class.java // Required for Generic Reification
).thenAccept { response ->
response.result?.forEach { partner ->
println(partner.name)
}
}Use OdxProxy.write
val updateVals = mapOf("name" to "New Name")
OdxProxy.write(
model = "res.partner",
ids = listOf(10, 11),
values = updateVals,
keyword = OdxClientKeywordRequest(),
id = null
).join() // or .get()Why: Odoo might send [id, name] array or false. This will crash serialization. Fix: Use val company: OdxMany2One.
Why: Odoo often sends false (Boolean) for empty strings. Fix: Use val email: OdxVariant.
Why: The client is internal. Fix: Use OdxProxy.method(...).
Why: Odoo can return HTTP 200 OK but contain a logic error in the JSON body. The library wraps this, but always be aware of OdxServerErrorException.