Implementation can be done in any order.
Domain models should be implemented under pkg
It should be implemented under internal/infrastructure
To implement the feature use case layer we have 2 main steps:
internal/usecase/interfaces
internal/usecase/interactor
and it should accept the context.Context
as its first parameter. Also most usecases may accept *usecase.Operator
which can be used to handle some authorization stuff.internal/usecase/interactor/
, and it should contain calls of the domain layer and the infrastucture layer.gqlgen library is used to generate the graphql code, Its a schema first approach so to develop new types or mutations, the declaration should done in schema.graphql
file, after schema declaration go generate ./internal/graphql
should be run to generate the related code.
The gqlgen library will generate the related code up down to the adapter layer represented in internal/adapter/graphql/controller_*.go
.
The adapter layer normally should relay on the use case layer. In this layer, codes should contains no business logic, but conversion between domain models and GraphQL types, and a call of the usecase layer.
It's recommended to unit test your code. Table driven design is the preferred way to provide multiple test cases for each function. You may use the assert package from testify to assert test results.
A simple code example for testing math.Max(x, y)
method:
package math
import (
"math"
"testing"
"github.com/stretchr/testify/assert"
)
func TestMax(t *testing.T) {
testCases := []struct {
name string
arg1 float64
arg2 float64
expected float64
}{
{
name: "arg1 < arg2",
arg1: 1.0,
arg2: 2.0,
expected: 2.0,
},
{
name: "arg1 > arg (with negative)",
arg1: -100,
arg2: -200,
expected: -100,
},
{
name: "arg1 < arg2 (floating point)",
arg1: -8.31373e-02,
arg2: 1.84273e-02,
expected: 1.84273e-02,
},
}
for _, tc := range testCases {
tc := tc
t.Parallel()
t.Run(tc.name, func(tt *testing.T) {
tt.Parallel()
actual := math.Max(tc.arg1, tc.arg2)
assert.Equal(tt, tc.expected, actual)
})
}
}
Points to consider while writing tests:
Test{FuncName}
, Test{TypeName}_{MethodName}