Skip to content

swaggest/usecase

Folders and files

NameName
Last commit message
Last commit date

Latest commit

90e267b · Dec 19, 2023

History

24 Commits
Dec 7, 2023
Dec 7, 2023
Sep 8, 2021
Dec 7, 2023
Jan 2, 2020
Dec 7, 2023
Oct 12, 2021
Apr 14, 2021
Jan 2, 2020
May 26, 2022
Jan 2, 2020
Feb 18, 2021
Sep 12, 2022
Sep 12, 2022
Dec 7, 2023
Dec 7, 2023
Dec 19, 2023
Sep 12, 2022
Sep 25, 2020
Sep 28, 2020
Sep 8, 2021
Apr 14, 2021

Repository files navigation

Use Case Interactor

Build Status Coverage Status GoDevDoc Code lines Comments

This module defines generalized contract of Use Case Interactor to enable The Clean Architecture in Go application.

Clean Architecture

Why?

Isolating transport layer from business logic reduces coupling and allows better control on both transport and business sides. For example the application needs to consume AMQP events and act on them, with isolated use case interactor it is easy to trigger same action with HTTP message (as a part of developer tools).

Use case interactors declare their ports and may serve as a source of information for documentation automation.

This abstraction is intended for use with automated transport layer, for example see REST.

Usage

Input/Output Definitions

// Configure use case interactor in application layer.
type myInput struct {
    Param1 int    `path:"param1" description:"Parameter in resource path." multipleOf:"2"`
    Param2 string `json:"param2" description:"Parameter in resource body."`
}

type myOutput struct {
    Value1 int    `json:"value1"`
    Value2 string `json:"value2"`
}

Classic API

u := usecase.NewIOI(new(myInput), new(myOutput), func(ctx context.Context, input, output interface{}) error {
    var (
        in  = input.(*myInput)
        out = output.(*myOutput)
    )

    if in.Param1%2 != 0 {
        return status.InvalidArgument
    }

    // Do something to set output based on input.
    out.Value1 = in.Param1 + in.Param1
    out.Value2 = in.Param2 + in.Param2

    return nil
})

Generic API with type parameters

With go1.18 and later (or gotip) you can use simplified generic API instead of classic API based on interface{}.

u := usecase.NewInteractor(func(ctx context.Context, input myInput, output *myOutput) error {
    if in.Param1%2 != 0 {
        return status.InvalidArgument
    }

    // Do something to set output based on input.
    out.Value1 = in.Param1 + in.Param1
    out.Value2 = in.Param2 + in.Param2

    return nil
})

Further Configuration And Usage

// Additional properties can be configured for purposes of automated documentation.
u.SetTitle("Doubler")
u.SetDescription("Doubler doubles parameter values.")
u.SetTags("transformation")
u.SetExpectedErrors(status.InvalidArgument)
u.SetIsDeprecated(true)

Then use configured use case interactor with transport/documentation/etc adapter.

For example with REST router:

// Add use case handler to router.
r.Method(http.MethodPost, "/double/{param1}", nethttp.NewHandler(u))