Thrift Types
You define thrift types in a shared schema file to pass structured data between services. The compiler reads this file and builds native code for your target programming languages. Engineering teams often share these schema files across many backend apps and data tools. When teams grant broad permissions to backend services, any client can call sensitive remote methods. Overly broad roles also let callers read or write every field inside shared data structures. How thrift types work across ser
Types: the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
You define thrift types in a shared schema file to pass structured data between services. The compiler reads this file and builds native code for your target programming languages. Engineering teams often share these schema files across many backend apps and data tools. When teams grant broad permissions to backend services, any client can call sensitive remote methods. Overly broad roles also let callers read or write every field inside shared data structures.
How thrift types work across services
Apache Thrift uses a simple text file to describe your data and service methods. Every field in a schema needs a clear type so both sides understand the payload. Base types cover simple values like booleans, signed integers of different sizes, and text strings. Binary fields hold raw byte arrays when you need to send files or encoded payloads. The schema language does not include unsigned integers because many target languages lack native support.
Container types let you group multiple items together inside a single message field. Lists hold an ordered sequence of items that can contain duplicate values. Sets hold unique items without a fixed order, which helps when checking for membership. Maps store key and value pairs that translate into native dictionaries or hash tables. You can nest these containers to build deep data structures for complex service calls.
Structs group related fields together into a named object with numbered field tags. Each field inside a struct gets a positive integer tag and a name. The wire protocol uses these number tags instead of field names to keep messages small. Unions work like structs, but they allow only one active field at a time. Exceptions also look like structs and let remote services return structured error details to callers. Enumerations map human names to thirty-two-bit integers for fixed sets of options.
Managing schema changes with field rules
After you write the schema, the compiler generates client and server stubs for each language. Every struct field uses a rule that marks it as required, optional, or default. If you mark a field as required, the sender must include it in every message. If a required field is missing on the wire, the reader rejects the whole payload. This strict rule makes schema updates hard when old and new apps run together.
Optional fields give teams a safer way to change schemas over time. If a sender skips an optional field, the wire message leaves those bytes out. When an old service reads a new message, it skips unknown field tags without failing. Default fields always travel across the wire when sent, even if you never set them. Most teams mark new fields as optional and never reuse old integer tags after deletion.
Types: architecture patterns and best practices
Continue reading? Get the full guide.
Free. No spam. Unsubscribe anytime.
What native schemas solve and what they leave open
Schema files solve the problem of passing typed data between apps written in different languages. They check that numbers, strings, and lists match what the receiving code expects to read. Transport layers and network rules also decide which machines or services can open a port. These native setups verify that a caller is allowed to talk to the remote server.
Still, schema rules and network checks only decide who can start a session. They do not inspect what individual requests or queries do while traffic is in flight. Once a client connects, a typed struct can still carry raw emails or card numbers. A valid request can also trigger destructive backend commands if the service role is wide. Teams still need a way to inspect live calls and mask sensitive fields in results.
Add runtime guardrails and masking beside your databases and APIs
Login rules, role grants, and CI checks govern who connects to your stack. Yet any allowed script, engineer, or AI agent still runs commands with the full scope of its role. For workloads on Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes, SSH, or internal HTTP services, hoop.dev sits beside the service as an open-source proxy, a sidecar for your database or API.
Before a query runs, hoop.dev guardrails check the statement against your rules. An AI Analyzer you configure can score intent or hold risky calls for human review. Next, hoop.dev data masking rewrites sensitive fields in responses, and each verdict is logged per listener. Explore the MIT-licensed project on GitHub.
Frequently asked questions
Why does Apache Thrift lack unsigned integer types?
Many popular programming languages do not support unsigned integers in their standard type systems. Leaving them out ensures that the compiler can map every schema field to native code.
What is the difference between a list and a set in a schema?
A list keeps items in a strict order and lets you include duplicate values. A set removes duplicates and does not keep a fixed order when sending data.
Should I mark new struct fields as required or optional?
You should mark new struct fields as optional so older services can still read messages. Required fields break older clients and servers if either side misses the expected value.
Related guides
In this post