Skip to content

HTTP REST API

An HTTP REST API as an input adapter in a hexagonal architecture serves as the interface for handling HTTP requests from clients. This adapter translates HTTP requests into calls to the core application's use cases and returns appropriate HTTP responses. Here's how it fits into the architecture:

Role of an HTTP REST API as an Input Adapter

  1. Handling HTTP Requests:

    • The adapter receives HTTP requests from clients (e.g., browsers, mobile apps).
  2. Request Translation:

    • It translates these HTTP requests into calls to the application's use cases (services). This involves parsing request parameters, headers, and bodies.
  3. Interfacing with Use Cases:

    • It interacts with the application's input ports, which represent the use cases. These ports expose the core application's functionality in a technology-agnostic manner.
  4. Generating HTTP Responses:

    • After processing the request, the adapter translates the results from the core application into HTTP responses, setting appropriate status codes and headers.

Benefits of HTTP REST API as Input Adapter

  • Decoupling: Decouples the external HTTP interface from the core application logic.
  • Separation of Concerns: Handles the specifics of HTTP request parsing and response formatting, allowing the core application to focus on business logic.
  • Testability: Allows the core application logic to be tested independently of the HTTP interface.
  • Flexibility: Supports different types of clients (e.g., web browsers, mobile apps) without changing the core application logic.

Using an HTTP REST API as an input adapter in hexagonal architecture ensures that the application remains adaptable and maintainable, supporting various external interfaces while keeping the core business logic isolated and testable.

How Torpedo implements HTTP adapter

Torpedo generates its code on top of Gin Gonic.

Controller

The created controller logic is split in two files once torpedo command is executed to generate the code. The outcome will be:

classDiagram
  inputGinBase <|-- InputGin
  inputGinBase : IService service
  inputGinBase : log.ILogger logger 
  inputGinBase: +Create()
  inputGinBase: +Read()
  inputGinBase: +Update()
  inputGinBase: +Delete()
  inputGinBase: +TQL()

As developer

As a developer your input logic MUST BE written into the Controller (InputGin) class in order to avoid that Torpedo code generation tool overwrite your code!

Data Transfer Object

The DTO is generated by Torpedo, letting you add custom fields if it is required and cannot be handled from the entity schema definition.

Basically Torpedo DTOs are an aggregation of different DTOs with their own semantic. Here is a diagram that illustrates this:

classDiagram
   class MetadataDTO
   class ReadOnlyDTO  
   class WriteableDTO
   class RelationshipsDTO
   class CustomDTO

  MetadataDTO --o FullDTO : Aggregation
  ReadOnlyDTO --o FullDTO : Aggregation
  WriteableDTO --o FullDTO : Aggregation
  RelationshipsDTO --o FullDTO : Aggregation
  CustomDTO --o FullDTO : Aggregation
  • MetadataDTO: This DTO contains the Torpedo entity generated fields like id, created and updated.
  • ReadOnlyDTO: When a field is set as readonly within the entity schema its input field will be mapped in this one.
  • WriteableDTO: Basically all the (non-readonly) defined fields will be written as fields of this DTO.
  • RelationshipsDTO: When a relationship is defined as hasMany, a linked list of linked entity will be placed here.
  • CustomDTO: Each time that you need to define a field that is usefull for some entity use case but is not defined on the schema, must be coded here.
  • FullDTO: This one is the aggregation DTO that contains all the preious DTO. So, when you need the complete DTO to map to the entity model, this is the one.

CustomDTO

Important: This is the only one DTO that is not overwritten by the autogeneration tool.

API endpoints

The API endpoints for CRUD operations are generated automatically per entity following the next pattern:

Operation Method Endpoint Description
Create POST /api/v1/$.spec.plural Create an entity object
Read GET /api/v1/$.spec.plural/:id Read an entity object
Update PUT /api/v1/$.spec.plural/:id Update an entity object
Delete DELETE /api/v1/$.spec.plural/:id Delete an entity object
Query POST /api/v1/$.spec.plural/query Query an entity object

GET the entire collection

At this point maybe you should notice that there isn't a GET /api/v1/$.spec.plural endpoint. This one is replaced by the Query endpoint letting you fetch all collection entities with filters, pagination and more.

Additionally, as shown at the entity definition Input section, the resource name can be set only for the input:

1
2
3
4
5
adapters:
    input:
      - type: http
        metadata:
          resourceName: "blog-post"
Operation Method Endpoint Description
Create POST /api/v1/blog-post Create an entity object
Read GET /api/v1/blog-post/:id Read an entity object
Update PUT /api/v1/blog-post/:id Update an entity object
Delete DELETE /api/v1/blog-post/:id Delete an entity object
Query POST /api/v1/blog-post/query Query an entity object