Skip to content

Definition

In the context of hexagonal architecture, a use case represents a specific business scenario or application logic that drives the core functionality of the system. It is an essential concept that encapsulates the core business rules and processes, ensuring that the application remains independent of external technologies, frameworks, and delivery mechanisms.

Role of Use Cases in Hexagonal Architecture

  1. Core Logic: Use cases define the core business logic and rules of the application.
  2. Independence: They are independent of external systems, frameworks, or user interfaces.
  3. Interfacing: Use cases interact with external systems through ports and adapters, maintaining a clean separation of concerns.
  4. Consistency: They ensure that the business rules are consistently applied across different delivery mechanisms (e.g., web, mobile, CLI).

Components of a Use Case in Hexagonal Architecture

  1. Input Ports: Interfaces that define the methods for executing the use case. These are the entry points for the application core.
  2. Use Case Implementation: The actual implementation of the business logic defined by the use case. It is the core application logic.
  3. Output Ports: Interfaces that define the methods for interacting with external systems or services (e.g., databases, message queues).
  4. Adapters: Implementations of input and output ports that connect the core application logic to external systems or delivery mechanisms.

Benefits of Use Cases in Hexagonal Architecture

  1. Separation of Concerns: Use cases encapsulate business logic, separated from technical details and delivery mechanisms.
  2. Testability: Since use cases are independent of external systems, they can be easily tested in isolation.
  3. Flexibility: The application can easily adapt to changes in external systems or delivery mechanisms without altering the core logic.
  4. Maintainability: Clear separation between business rules and technical details leads to cleaner, more maintainable code.

In hexagonal architecture, use cases are central to defining and managing the core business logic. They ensure that the application remains adaptable, testable, and maintainable by decoupling the business rules from the external systems and user interfaces. This approach fosters a clean architecture where the core logic is insulated from external changes, promoting long-term sustainability and flexibility.

How Torpedo works with Use Cases

Based on the user defined yaml file, Torpedo will create the needed dir struct and all the use case skeleton files. The use case directory should look like:

    |_ your_use_case
       |_ inputs
          |_ http                  // dir to add your controllers logic and DTOs.
       |_ outputs                  // dir to put all your repository logic related to your use case.
       |_ testing
          |_ mocks                 // dir to add your custom JSON mocks files or others.
       |   
       |_ torpedo_use_case_base.go // autogenerated struct with defined entities dependencie.
       |_ use_case.go              // UseCase struct where your use case code must be writen
       |_ use_case_test.go         // use case tests
  • torpedo_use_case_base.go: The base code generated by Torpedo includes a pointer to a provided loggger and all the related entities' service.
  • use_case.go: The main use case class that extends from the base use case class. This is where your business logic must be placed.
  • use_case_test.go: The well known test file to write your use case tests.
  • inputs/http: This is the place to code your Controller logic and DTOs.
  • outputs: This dir is to write the ouput adapters code raleated to the use case if you have one.
  • testing: All the testing releated files should be located here.

Yaml definition

document root ($)

Field Value Description
version torpedo.darksub.io/v1.0 The version of the schema
kind useCase Means that the yaml describes an use case object
spec object The spec encapsulate the use case definition

$.spec

Field Value Description
name string The use case name, should be camel case
description string A brief description about the use case
domain object Domain linked configurations

$.spec.domain

Field Value Description
entities []string (path list) The involved entities (yaml definitions) in the use case.

Yaml example

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
  1. 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

Writing your use case code

Following the section Quick start/Create a project/ Use Cases example, you will cover all needed to write your business logic!