Core Taxi Language
Get familiar with the taxi syntax
Taxi is a language for documenting data schemas - such as data models, and the contracts of APIs. Taxi describes data semantically, which allows powerful tooling to discover and map data based on it's meaning, rather than the name of a field.
Taxi provides a lightweight way to describe the meaning of data in a consistent, business friendly language.
Overview
namespace taxi.demo // Namespaces are optional, but recommended.
@SomeAnnotation
model Person {
@Id // Annotations are supported at both class and field level
id : PersonId inherits Int // Inline inheritance allow succinct semantic types
/** Comments can be defined in either
* block style, or // inline style
*/
firstName : FirstName inherits String
lastName : String // You don't have to use semantic types - but it is recommended
friends : Person[] // Lists are supported
spouse : Person? // '?' indicates nullable types
}
Key Concepts
- Types and Models provides a look into how to create a share semantic data models.
- Describing services outlines how to document the API's, their inputs and outputs.
- Taxi Projects describes how to bundle it all together into a package
Syntax and Files
Taxi files are simple text files, saved with a .taxi
suffix.
Taxi is it's own language, and doesn't use things like JSON or YAML. This means that we can specs that are
expressive, and much easier to understand than the JSON / YAML counterparts.
Namespaces
Like in most languages, things in Taxi (types, services, operations, etc) need to have a unique name.
To help prevent name clashes, Taxi uses namespaces - simply a way of disambiguating between two things with the same name.
namespace customers
type Name inherits String // The fully qualified name is customers.Name
Namespaces in Taxi are analogous to namespaces
in C#, or package
in Java / Kotlin.
When namespaces are in use, the following rules apply:
- Type references within the same namespace need not qualify their references
- Type references within a different namespace must use a fully qualified reference
Namespaces can be declared in two ways.
Single namespace files
If everything in a single file belongs to the same namespace, simply add namespace xxx
at the top of the file.
Everything that is declared in the file becomes part of the namespace.
namespace customers
type Name inherits String // The fully qualified name is customers.Name
Multi-namespace files
If you have multiple namespaces within the same file, you can define namespaces using curly brace syntax:
namespace people {
// fullyQualifiedName is people.Name
type Name inherits String
}
namepace pets {
// fullyQualifiedName is pets.Name
type Name inherits String
}
Imports
Imports are a way of including a type declared in another file. When a type or model is imported, it can be referenced using it's name, rather than requiring the fully qualified name.
Imports come before a namespace declaration.
import people.Name
namespace customers
// The same as:
// type customers.CustomerFirstName inherits people.Name
type CustomerFirstName inherits Name