In the last blog post before the summer holidays, we explored the world of API description using TypeSpec. Today, we're shifting gears to another powerful tool in the API landscape - the Taxi language. We'll delve into its relevance in building APIs, particularly how it can transform data models into OpenAPI descriptions. We'll continue with our retail example for consistency.
Understanding Taxi Language
Taxi language is a domain-specific language (DSL) designed for describing data models in a clear and concise manner. It's a language-agnostic tool, meaning it can be used across various programming languages. Taxi language is particularly useful in the context of APIs, where it can serve as a bridge between different systems and services.
Building APIs with Taxi Language
In the retail domain, APIs are crucial for connecting various systems and services, such as inventory management, payment processing, and customer relationship management. With Taxi language, you can describe the data models that these APIs use in a structured and standardised way.
Let's consider a simple example. Suppose we have a Customer
model in our retail API. In Taxi language, we might describe this model as follows:
1namespace de.codecentric.retail 2 3type CustomerId inherits String 4type FirstName inherits String 5type LastName inherits String 6type Email inherits String 7type PhoneNumber inherits String 8 9model Customer { 10 id: CustomerId 11 firstName: FirstName 12 lastName: LastName 13 email: Email 14 phoneNumber: PhoneNumber 15}
Within the description language types describe a specific piece of information. While the model describes the contract and the structure of the data. Types should therefore be used for the entire organisation. The models, on the other hand, should have a specific owner.
Once you've described your data models using Taxi language, you can transform them into an OpenAPI description. OpenAPI is a widely used standard for describing RESTful APIs. It provides a rich set of features for defining APIs, including operations, parameters, responses, and more.
We need to get our workspace ready once again. With Taxi being part of sdkman the install process is quite easy.
1❯ sdk install taxi 2We periodically need to update the local cache. Please run: 3 4 $ sdk update 5 6 7Downloading: taxi 1.40.0 8 9In progress... 10 11######## 100.0% 12 13Installing: taxi 1.40.0 14Done installing! 15 16Do you want taxi 1.40.0 to be set as default? (Y/n): Y 17 18Setting taxi 1.40.0 as default.
After creating a folder for this little experiment. We can initialise Taxi.
1taxi init
This brings up the following prompt. Setting up a project group, name and version.
1Taxi 1.40.0 @6fa3e81 2Project group (eg., com.acme): de.codecentric.retail 3Project name: customer 4Project version [0.1.0]: 0.1.0 5Source directory [src/]: 6Creating project com.codecentric.retail/customer v0.1.0 in directory /Users/daniel/_new_ideas/taxi-playground/retail/customer 7Writing config to /Users/daniel/_new_ideas/taxi-playground/retail/customer/taxi.conf 8Generating source directory at /Users/daniel/_new_ideas/taxi-playground/retail/customer/src 9Finished
This gives us the following folder structure.
1.gitignore 2.taxi 3.vscode 4src 5taxi.conf
Now we have to extend the taxi configuration file with a plugin description to create an OpenAPI definition out of the taxi description later on.
1name: de.codecentric.retail/customer
2version: 0.1.0
3sourceRoot: src/
4
5plugins: {
6 taxi/open-api: {
7 outputPath: "open-api"
8 services: ["de.codecentric"]
9 }
10}
Back to the types and the model from the beginning. To describe operations for the model we have to declare a service first. With Annotations we are able to the relation to HTTP which leads then to the possibility to create an OpenAPI definition out of this information.
1namespace de.codecentric.retail
2
3type CustomerId inherits String
4type FirstName inherits String
5type LastName inherits String
6type Email inherits String
7type PhoneNumber inherits String
8
9model Customer {
10 id: CustomerId
11 firstName: FirstName
12 lastName: LastName
13 email: Email
14 phoneNumber: PhoneNumber
15}
16
17@HttpService(baseUrl = "http://api.codecentric.de")
18service CustomerService {
19 @HttpOperation(method = "GET", url = "/customers")
20 operation getAllCustomers(): Customer[]
21
22 @HttpOperation(method = "GET", url = "/customers/{id}")
23 operation getCustomerById(id: CustomerId): Customer
24
25}
To transform a Taxi description into OpenAPI we just have to use the CLI to create the definition.
1taxi build
This gives us a simple representation of the description, which shows already the potential of using taxi for the subsequent transformation.
1openapi: 3.0.1
2info:
3 title: CustomerService
4 version: 1.0.0
5servers:
6- url: http://api.codecentric.de
7paths:
8 /customers:
9 get:
10 parameters: []
11 responses:
12 "200":
13 content:
14 application/json:
15 schema:
16 type: array
17 items:
18 $ref: '#/components/schemas/de.codecentric.Customer'
19 /customers/{id}:
20 get:
21 parameters: []
22 responses:
23 "200":
24 content:
25 application/json:
26 schema:
27 $ref: '#/components/schemas/de.codecentric.Customer'
28components:
29 schemas:
30 de.codecentric.Customer:
31 type: object
32 properties:
33 id:
34 type: string
35 x-taxi-type:
36 name: de.codecentric.CustomerId
37 create: false
38 firstName:
39 type: string
40 x-taxi-type:
41 name: de.codecentric.FirstName
42 create: false
43 lastName:
44 type: string
45 x-taxi-type:
46 name: de.codecentric.LastName
47 create: false
48 email:
49 type: string
50 x-taxi-type:
51 name: de.codecentric.Email
52 create: false
53 phoneNumber:
54 type: string
55 x-taxi-type:
56 name: de.codecentric.PhoneNumber
57 create: false
If you need additional elements in the representation of OpenAPI you're welcome to add these to the existing plugin or write a new one.
Conclusion
Taxi language offers a powerful and flexible way to describe data models for APIs. By transforming Taxi descriptions into OpenAPI, you can leverage the wide range of tools and libraries that support the OpenAPI standard, making your API development process more efficient and effective.
As we continue to explore the world of APIs, it's clear that tools like Taxi language can play a crucial role in modern software development. Whether you're building a retail API or any other kind of API, these tools can help you design, implement, and maintain your APIs with precision and ease.
References
GitHub - danielkocot/taxi-playground: A playground to play around with Taxi language.
Charge your APIs Volume 10: Crafting API Definitions with TypeSpec
More articles
fromDaniel Kocot
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Daniel Kocot
Senior Solution Architect / Head of API Consulting
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.