-
Notifications
You must be signed in to change notification settings - Fork 4
data containers
#Intro Data containers, or DTOs (data transfer objects) are run-time incarnations of schema types. Their implementations should exist for every target programming language. These classes can be marshalled into one of over-the-wire representations and unmarshalled back.
In many cases there more than one implementation of data containers will be provided.
#Raw containers Raw containers are generic implementations that don't depend on particular schema. They provide minimal type safety but a lot of run-time checks, they're mostly suitable for general-purpose framework and library code. Examples:
trait RawRecordData(val schema: RecordSchema, val meta: Option[RawData]) {
def get(field: Field): RawData
def get(field: Field, schema: Schema): RawData
def set(field: Field, schema: Schema, value: RawData): Unit
}
trait RawMapData(val schema: MapSchema, val meta: Option[RawData]) {
def get(key: RawData): RawData
def get(key: RawData, schema: Schema): RawData
def set(key: RawData, schema: Schema, value: RawData): Unit
}
Notice how there are pairs of get
functions: one gives the default
representation, another one takes a specific model to return.
#Type safe containers Type safe containers can come in different flavors with different degrees of type safety, depending on the implementation language. In many cases they are generated basing on the schema. For example they can look like this:
trait FileRecord {
def name: string
def name_=(name: string): Unit
def owner: UserId
def owner_=(owner: UserId):Unit
def getOwner(schema: Schema[User]): User
def setOwner(schema: Schema[User], owner: User): Unit
}
#Value containers Value containers such as record fields, union tags, map values or list entries are all structured in the same way. There are several nested layers of information:
- At the innermost layer there is actual data container such as
RawRecordData
orStringPrimitive
- There is an
Either[Error,Data]
wrapper around it. We support fine-grained errors, and any part of the data tree hold an error. - Then there is a
Future
around it, because services can be asked to resolve any part of the tree asynchronously - Finally there is
MultiValue
which represents an instance of [MultiType
](schema overview#multi-types). This is a map from representation types to corresponding values. For non-pivotable fields it will contain only one entry
Graphically: