Databases 7 min read

Designing a Minimalist Client API for a Rust Database with TCP Serialization

This article explains how to expose a lightweight, dependency‑free client API for a Rust‑based database by defining a simple TCP‑based JSON serialization protocol, detailing non‑functional and functional requirements, the Message and Command structures, and providing a concrete Ping command implementation in Rust.

Architecture Development Notes
Architecture Development Notes
Architecture Development Notes
Designing a Minimalist Client API for a Rust Database with TCP Serialization

Part 1 – Exposing an API to Clients

Background

Every database needs to expose an API for client interaction. While not strictly required for studying internal structures, an entry point is needed for end‑to‑end testing.

Requirements

Non‑functional Requirements

Readability – Essential for any component; the first component should be easy to understand to avoid confusion.

Minimal Dependencies – The component must avoid unnecessary dependencies to keep the learning focus on data structures and algorithms.

Simplicity and Extensibility – Simpler components improve readability and make adding new commands require little boilerplate.

Functional Requirement

The only functional requirement is the ability to trace requests by request ID for debugging.

Design

Different databases expose different client interfaces. Examples include:

SQLite – Embedded SQL database with a C client library.

Redis – In‑memory database accessed over TCP using the RESP protocol.

CouchDB – Provides a RESTful HTTP API.

For our research‑focused database we choose a lightweight JSON‑based protocol over TCP, prioritising minimal dependencies and simplicity.

The serialization protocol is based on a Message structure consisting of a small binary header and an optional JSON payload.

Implementation

We start by defining a Command that interprets client requests. The following shows a simple Ping command implementation:

<code>#[derive(Debug)]
pub struct Ping;

#[derive(Serialize, Deserialize)]
pub struct PingResponse {
    pub message: String,
}

impl Ping {
    pub async fn execute(self) -> Result<PingResponse> {
        Ok(PingResponse {
            message: "PONG".to_string(),
        })
    }
}
</code>

The Message struct defines the wire format:

<code>pub struct Message {
    /// Identifier for payload deserialization
    pub cmd_id: CommandId,
    /// Unique request identifier for tracing and debugging (must be UTF‑8)
    pub request_id: String,
    /// Optional request payload
    pub payload: Option<Bytes>,
}
</code>

Additional header fields such as a checksum or timestamp may be added in the future.

Building a Message from a TCP connection is performed as follows:

<code>impl Message {
    pub async fn try_from_async_read(tcp_connection: &mut TcpStream) -> Result<Self> {
        let cmd_id = CommandId::try_from(tcp_connection.read_u8().await?)?;
        let request_id_length = tcp_connection.read_u32().await?;
        let request_id = {
            let mut buf = vec![0u8; request_id_length as usize];
            tcp_connection.read_exact(&mut buf).await?;
            String::from_utf8(buf).map_err(|_| {
                Error::InvalidRequest(InvalidRequest::MessageRequestIdMustBeUtf8Encoded)
            })?
        };
        let payload_length = tcp_connection.read_u32().await?;
        let payload = if payload_length > 0 {
            let mut buf = vec![0u8; payload_length as usize];
            tcp_connection.read_exact(&mut buf).await?;
            Some(buf.into())
        } else {
            None
        };
        Ok(Self {
            cmd_id,
            request_id,
            payload,
        })
    }
}
</code>

Conclusion

This article described how rldb processes client requests, including serialization, deserialization, and request‑ID propagation. The next chapter will cover cluster bootstrapping, node discovery, failure detection, and the gossip protocol implementation.

DatabaseRustSerializationTCPAPICommand
Architecture Development Notes
Written by

Architecture Development Notes

Focused on architecture design, technology trend analysis, and practical development experience sharing.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.