1. Initialize
Lets begging with our first application built with Torpedo!. We will be building a fly reservation app called Booking Fly
following these simple steps:
- Initialize the project
- Code generation
- Dependency Injection
- Writing use case: Booking a fly
- Run it!
We encourage you to follow all the steps to create it, however if you need to check something here is a link to the application repo: Booking Fly.
Torpedo Init
Creating your first application based on an entity definition requires a torpedo initialization. Following the next command
your project will be initialized.
First you need to create a project dir and be located on it:
| mkdir booking-fly && cd booking-fly
|
After that you would initialize the torpedo project:
| ~/projects/booking-fly> torpedo init
|
.torpedo
dir struct
The .torpedo
dir struct is so simple. You need a directory to put your entities definitions and a directory to put the
use cases definitions. The next is an example of it:
| booking-fly/
|_ .torpedo
|
|_ entities Entities yaml files goes here
| |_ docs Entities MD documentation
| | |_ user.md
| |_ user.yaml
|
|_ use_cases Use cases yaml files goes here
| |_ docs Use cases MD documentation
| | |_ booking_fly.md
| |_ booking_fly.yaml
|
|_ app.yaml The application yaml definition
|
Entity definition
The following snippets illustrates how to create the entities definition for the Booking Fly example:
For further information refers to the section entity schema
.torpedo/entities/user.yaml
| version: torpedo.darksub.io/v1.0
kind: entity
spec:
name: "user"
plural: "users" #(1)!
description: "The frequent flyer user"
doc: |
The user entity represents a system user but also a frequent flyer.
This entity is only for the example purpose.
schema:
reserved:
id:
type: ulid #(2)!
fields:
- name: name
type: string
description: "The user full name"
- name: email
type: string
description: "The user contact email"
- name: password #(3) it is not recommended to save passwords, this is an example only
type: string
encrypted: true
description: "The user system password"
- name: plan
type: string
description: "The user membership plan"
validate:
list:
values:
- GOLD
- SILVER
- BRONZE
- name: miles
type: integer
description: "The accumulated flyer miles"
relationships:
- name: trips
type: $rel
ref: ".torpedo/entities/trip.yaml"
cardinality: hasMany
load:
type: nested
metadata:
maxItems: 100
adapters:
input:
- type: http
output:
- type: memory #(4)!
|
- The plural attribute is used for instance to create the entity RESTful API path
- The id field is reserved and can be only one of: ulid or uuid.
- The encrypted field attribute is used to store the field value into the repository as encrypted instead of plain value.
This example illustrates how it works, but a password shouldn't be stored in the repo.
- The memory output adapter is usually for testing purpose.
.torpedo/entities/trip.yaml
| version: torpedo.darksub.io/v1.0
kind: entity
spec:
name: trip
plural: trips
description: "The user fly trip reservations"
doc: |
The trip entity handles all data related with the frequent flyer trip
schema:
reserved:
id:
type: ulid
fields:
- name: departure
type: string
description: "The trip departure airport"
- name: arrival
type: string
description: "The trip arrival airport"
- name: miles
type: integer
description: "The trip miles"
- name: from
type: date
description: "The trip from date"
- name: to
type: date
description: "The trip to date"
adapters:
input:
- type: http
output:
- type: memory
|
Use case definition
The use cases are the corner stone of any application. Your custom business logic should be defined as use cases. Torpedo introduces
a simple but powerful use case definition. The following example is the fly reservation use case:
.torpedo/use_cases/booking_fly.yaml
| version: torpedo.darksub.io/v1.0
kind: useCase
spec:
name: "BookingFly"
description: "Fly reservation use case"
doc: | #(1)!
Given a frequent flyer user should be able to do a booking fly from our well known fly routes, selecting the
departure airport and the arrival airport, also setting up the from-to fly dates. If the booking is successful, so the
system should calculate the user awards and upgrade it
domain:
entities:
- user.yaml
- trip.yaml
|
- The documentation can be placed in a markdown file into the folder
.torpedo/use_cases/docs/booking_fly.md
and you can refer it from the
yaml file as doc: booking_fly.md
Documentation as Markdown files
The documentation can be placed in a markdown file into the folder .torpedo/use_cases/docs/booking_fly.md
and you can link it from the
yaml file as doc: booking_fly.md
Application definition
The application definition is the most important file because here is described your app.
The following example shows how to define the Booking Fly app:
.torpedo/app.yaml
| version: torpedo.darksub.io/v1.0
kind: app
spec:
name: "Booking Fly System"
description: "Application example"
stack:
lang: go
package: "github.com/darksubmarine/booking-fly" #(1)!
domain:
entities:
- user.yaml
- trip.yaml
useCases:
- booking_fly.yaml
|
- Replace it with your package (git) name
Torpedo Fire
Once that you have the project dir, the entity definitions, the use cases definitions and your app definition, running
the Torpedo command line tool the code will be generated:
| ~/projects/booking-fly> torpedo fire
|
The ouput should be like:
| mkdir: ~/projects/booking-fly/dependency
mkdir: ~/projects/booking-fly/domain
mkdir: ~/projects/booking-fly/domain/entities
mkdir: ~/projects/booking-fly/domain/use_cases
mkdir: ~/projects/booking-fly/domain/testing
mkdir: ~/projects/booking-fly/domain/inputs
mkdir: ~/projects/booking-fly/domain/outputs
Entities parsed:
- ~/projects/booking-fly/.torpedo/entities/user.yaml
- ~/projects/booking-fly/.torpedo/entities/trip.yaml
Use cases parsed:
- ~/projects/booking-fly/.torpedo/use_cases/booking_fly.yaml
+ Build has been successfully!
|
This command will generate the project struct and the autogenerated code. So something like the following project should be created:
| booking-fly/
|_ .torpedo
|_ dependency
|_ domain
|_ entities
|_ ...
|_ inputs
|_ outputs
|_ testing
|_ use_cases
|_ ...
|_ ...
|_ config-dev.yaml
|_ go.mod
|_ go.sum
|_ main.go
|
Once that the code has been generated, the dependencies should be installed:
| ~/projects/booking-fly> go mod tidy
|
Now your project is ready to run with the following command:
| ~/projects/booking-fly> ENVIRONMENT=dev go run main.go
|
Missing API endpoints
You should notice about that Use Case API endpoints are not available so far. To get it working as expected we need to proceed
with the Dependency Injection section.