A CLI (Command Line Interface) to create your apps with Service Weaver, using gomigrate, sqlc, and Fiber.
The choice of the name "Boneless" for this CLI tool draws inspiration from the historical figure Ivar the Boneless. Ivar the Boneless was a legendary Viking leader known for his strategic prowess, adaptability, and agility on the battlefield. In a similar vein, the name "Boneless" for the CLI tool reflects these qualities in the context of software development. It symbolizes the tool's ability to navigate through complex tasks and challenges effortlessly, just as Ivar the Boneless maneuvered through battles with agility and cunning. By associating the CLI tool with Ivar the Boneless, the name not only captures the spirit of adaptability and flexibility but also adds a touch of historical significance to the tool's identity. In summary, the name "Boneless" pays homage to Ivar the Boneless and serves as a metaphor for the CLI tool's ability to conquer development obstacles with ease and grace.
These tools, when used alongside Boneless, contribute to various aspects of the development process. Service Weaver aids in managing microservices, go-migrate simplifies database migrations, SQLC enhances database code generation, and Fiber provides a robust framework for building web applications. Together, they enhance the functionality and development experience of Boneless.
Let's dive into the architecture used in Boneless. In this section, we will explore the intricacies and key details of the architecture that powers the project created by Boneless.
Boneless was inspired by Clean Architecture and offers templates that follow its core concepts. The templates provided by Boneless facilitate the creation of modular, maintainable, and testable codebases by promoting a clear separation of concerns and the independence of business logic from external dependencies. By using Boneless templates, developers can jumpstart their projects with a well-organized structure that aligns with Clean Architecture, enabling them to focus on implementing the domain-specific logic while adhering to best practices. Boneless empowers developers to build robust and scalable applications, leveraging the benefits of Clean Architecture for easier understanding, maintenance, and evolution over time.
Based on Service Weaver, which generates connections between components using gRPC, has greatly facilitated the development of our applications.
.
├── cmd
│ └── main.go
├── go.mod
├── go.sum
├── internal
│ ├── app
│ │ ├── component.go
│ │ ├── db
│ │ │ ├── migrations
│ │ │ │ └── schema.sql
│ │ │ ├── query.sql
│ │ │ └── sqlc.yaml
│ │ ├── entity.go
│ │ ├── store
│ │ │ ├── db.go
│ │ │ ├── models.go
│ │ │ └── query.sql.go
│ │ └── weaver_gen.go
│ └── bff
│ ├── bff.go
│ ├── router.go
│ └── weaver_gen.go
└── weaver.toml
In this structure, we can observe the organization of directories and files in the repository. The cmd
directory contains the main.go
file, which is responsible for starting the application. The go.mod
and go.sum
files are used to manage project dependencies.
The internal
the directory is where the main implementation of the application resides. Inside, we have the app
directory, which contains components related to the application's domain, such as entities and business logic. The db
directory is used to store files related to the database layer, such as migrations and SQL queries.
The store
directory contains files related to data storage, such as the implementation of database access. The bff
directory contains files related to the implementation of the Backend for the Frontend layer.
Lastly, the weaver.toml
file is used to configure Service Weaver, which facilitates generating connections between application components using gRPC.
This directory and file structure reflects the adopted architecture in the repository, following the principles of Clean Architecture and facilitating the organization and maintenance of the application's source code.
Let's create our first project from scratch using Boneless!
First, we need to install the binary of Service Weaver, Go Migrate, SQLC, and Boneless. Even so, I suggest you read the documentation of all of them on your official websites.
$ go install -tags 'mysql sqlite3' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
$ go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
$ go install github.com/ServiceWeaver/weaver/cmd/weaver@latest
$ go install github.com/renanbastos93/boneless/cmd/boneless@latest
To ensure a smooth setup of your Boneless project, let's install all the dependencies, including Boneless itself. If you're not using macOS, you can access their website for detailed instructions on installing Boneless and its dependencies specific to your operating system.
$ boneless help
Usage: boneless [target]
Targets:
help Show commands for use
version Show version
new <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
create-scratch <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
build Build the Weaver component with SQLC
make-migrate <app-name> <name> Create a new migration for an app
migrate <app-name> <up|down> Run migrations for an app
create-app <app-name> Create a new app based on a template
build-app <app-name> Build an app using Weaver and SQLC
run Run the project using Weaver
Parameters:
<app-name> Name of the app to create or run migrations on
<name> Name of the migration to create
<up|down> Specify "up" to apply migrations or "down" to rollback migrations
<sql|sqlite> Specify "sql" to use some SQL "sqlite3" to use sqlite3 and it is the default
Examples:
boneless help
boneless version
boneless create-scratch
boneless build
boneless make-migrate my-app migration-name
boneless migrate my-app up
boneless create-app my-app
boneless build-app my-app
boneless run
After that is installed, let's create our first project from scratch using Boneless, a framework based on clean architecture, to efficiently generate and organize the project structure, implement functionality, and deploy it with ease.
Let's dive right in and create a project from scratch, and then run it to see Boneless in action!
For starting we've been thinking of a simple API that uses CRUD.
# First, we need to create go.mod file
$ go mod init bone
# After that let's call command boneless to start a project
# As a default, it was created using SQLite3
$ boneless new
# Here we going to execute all migrations of the `internal/app`
$ boneless migrate app up
# Now, we can use the command `run`
boneless run
__ __ ______ __ ____
/ /_ ____ ____ ___ / / ___ _____ _____ / ____/ / / / _/
/ __ \ / __ \ / __ \ / _ \ / / / _ \ / ___/ / ___/ / / / / / /
/ /_/ // /_/ / / / / // __/ / / / __/ (__ ) (__ ) / /___ / /___ _/ /
/_.___/ \____/ /_/ /_/ \___/ /_/ \___/ /____/ /____/ \____/ /_____//___/
running...
PID: <process-id>
BFF listener available on 127.0.0.1:8090
┌───────────────────────────────────────────────────┐
│ Fiber v2.48.0 │
│ http://127.0.0.1:8090 │
│ │
│ Handlers ............. 6 Processes ........... 1 │
│ Prefork ....... Disabled PID ............. 40506 │
└───────────────────────────────────────────────────┘
╭───────────────────────────────────────────────────╮
│ app : main │
│ deployment : <uuid> │
╰───────────────────────────────────────────────────╯
Wow, here we created your first app using Boneless. Now, we can be using it, let's use cURL for testing.
# Get All Examples
$ curl --location --request GET 'http://127.0.0.1:8090/examples'
# returns empty because we haven't data yet
# []
# Create an Example
$ curl --location --request POST 'http://127.0.0.1:8090/examples/' \
--header 'Content-Type: application/json' \
--data-raw '{
"message": "Hello everyone"
}'
# After you created anything we can get an example just
# but you need to know the ID for it
$ curl --location --request GET 'http://127.0.0.1:8090/examples/:id'
# example data
{
"id": 2104895800, # id is random
"created_at": "2023-07-20T03:22:37.289-03:00",
"message": "Hello everyone"
}
That's all folks!