Skip to content

Commit e8be2bb

Browse files
authored
Update blueprint with standard package layout (#51)
1 parent a4c8785 commit e8be2bb

30 files changed

+401
-282
lines changed

.assay-it.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"suites": [
3-
"http/suites/petshop.go"
3+
"internal/http/suites/petshop.go"
44
]
55
}

README.md

+20-16
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,26 @@ Before Getting started, you have to ensure
8888

8989
The structure resembles the mixture of [Standard package layout](https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1) and [Hexagonal architecture](https://medium.com/@matiasvarela/hexagonal-architecture-in-go-cfd4e436faa3). The proposed structure is better version of Hexagonal architecture that follows Golang best practices:
9090

91-
1. the root package contains core types to describe domain of your application. It contains simple types that has no dependency to technology but their implements core logic and use-cases.
91+
1. the root is aws cdk application
92+
93+
2. Sub-packages to isolate dependencies to external technologies so that they act as bridge between your domain and technology adaptation. `internal` holds sub-packages internal to applications. `pkg` are sharable clients
9294

93-
2. Use sub-packages to isolate dependencies to external technologies so that they act as bridge between your domain and technology adaptation.
94-
95-
3. Main packages build lambda functions and ties everything together.
95+
4. `cmd` contains main packages that build lambda functions and ties everything together.
9696

9797
```
98-
github.com/.../the-beautiful-app
99-
├─ pet.go // the root defines domain types, unit test
100-
├─ ... // "algebra" of your application
98+
github.com/.../the-beautiful-app
99+
├─ petshop.go // aws cdk main application
100+
|
101+
├─ internal/awspetshop // IaC, aws cdk application
101102
|
102-
├─ storage.go // defines capability requires to store core
103+
├─ internal/core // the root defines domain types, unit test
104+
| | // "algebra" of your application. contains core
105+
| | // types to describe domain of your application.
106+
| | // It contains simple types that has no dependency
107+
| | // to technology but their implements core logic
108+
| | // and use-cases.
109+
| |
110+
| └─ storage.go // defines capability requires to store core
103111
| // objects at the external storage, hex-arch
104112
| // use "port" concept to depict it
105113
|
@@ -116,14 +124,10 @@ github.com/.../the-beautiful-app
116124
|
117125
├─ internal/mock // shared mock
118126
|
119-
├─ http // public REST API exposed by application.
127+
├─ internal/http // public REST API exposed by application.
120128
| ├─ petshop.go // collection of petshop endpoints impl. by app
121129
| | // endpoints consumer services using ports
122130
| |
123-
| ├─ api // public objects used by API
124-
| | └─ pet.go
125-
| ├─ curl // client library
126-
| | └─ petshop.go
127131
| └─ suites // testing suites for api endpoint(s)
128132
|
129133
├─ cmd // executables of the project
@@ -134,8 +138,8 @@ github.com/.../the-beautiful-app
134138
| └─ server // run application as standalone server
135139
| └─ main.go
136140
|
137-
├─ cloud // IaC, aws cdk application
138-
| └─ ... // orchestrate ops model
141+
├─ pkg/api // public domain objects used by application
142+
| // client library
139143
|
140144
└─ .github // CI/CD with GitHub Actions
141145
└─ ...
@@ -182,7 +186,7 @@ In few seconds, the application becomes available at
182186
curl https://xxxxxxxxxx.execute-api.eu-west-1.amazonaws.com/api
183187
```
184188

185-
The api is protected by AWS IAM, request has to be signed.
189+
The write path of api is protected by AWS IAM, request has to be signed.
186190
Either use example client `cmd/petshop-cli` or curl directly
187191

188192
```bash

cdk.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"app": "go mod download && go run cloud/blueprint.go",
2+
"app": "go mod download && go run petshop.go",
33
"requireApproval": "never",
44
"context": {
55
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
@@ -8,4 +8,4 @@
88
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
99
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true
1010
}
11-
}
11+
}

cloud/blueprint.go

-65
This file was deleted.

cloud/blueprint_test.go

-30
This file was deleted.

cmd/lambda/console/main.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
import (
4+
"github.com/aws/aws-lambda-go/lambda"
5+
"github.com/fogfish/blueprint-serverless-golang/internal/services/restapi"
6+
httpd "github.com/fogfish/gouldian/v2/server/aws/apigateway"
7+
)
8+
9+
func main() {
10+
api := restapi.NewPetShopAPI()
11+
12+
lambda.Start(
13+
httpd.Serve(
14+
api.Create(),
15+
),
16+
)
17+
}

cmd/lambda/petshop/main.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@ package main
22

33
import (
44
"github.com/aws/aws-lambda-go/lambda"
5-
"github.com/fogfish/blueprint-serverless-golang/cmd"
5+
"github.com/fogfish/blueprint-serverless-golang/internal/services/restapi"
66
httpd "github.com/fogfish/gouldian/v2/server/aws/apigateway"
77
)
88

99
func main() {
10-
api := cmd.NewPetShopAPI()
10+
api := restapi.NewPetShopAPI()
1111

1212
lambda.Start(
1313
httpd.Serve(
1414
api.List(),
15-
api.Create(),
1615
api.Lookup(),
1716
),
1817
)

cmd/petshop-cli/bug.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "B00",
3+
"category": "bug",
4+
"price": 99.99
5+
}

cmd/petshop-cli/main.go

+44-11
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,34 @@ import (
77
"os"
88

99
"github.com/aws/aws-sdk-go-v2/config"
10-
"github.com/fogfish/blueprint-serverless-golang/http/curl"
10+
"github.com/fogfish/blueprint-serverless-golang/pkg/api"
1111
"github.com/fogfish/gurl/awsapi"
1212
"github.com/fogfish/gurl/v2/http"
1313
)
1414

15-
// go run main.go https://XXXXXXXXXX.execute-api.eu-west-1.amazonaws.com
1615
func main() {
17-
fmt.Println(os.Args)
16+
if len(os.Args) == 1 {
17+
fmt.Printf("petshop-cli https://XXXXXXXXXX.execute-api.eu-west-1.amazonaws.com [pet.json]\n")
18+
}
1819

19-
cfg, err := config.LoadDefaultConfig(context.Background())
20-
if err != nil {
21-
panic(err)
20+
host := os.Args[1]
21+
if len(os.Args) == 3 {
22+
create(host, os.Args[2])
23+
} else {
24+
list(host)
2225
}
26+
}
2327

24-
curl := curl.NewPetShop(
25-
http.New(awsapi.WithSignatureV4(cfg)),
26-
os.Args[1],
27-
)
28+
func list(host string) {
29+
curl := api.NewPetShop(http.New(), host)
2830

2931
pets, err := curl.List(context.Background())
3032
if err != nil {
3133
panic(err)
3234
}
3335
output(pets)
3436

35-
if pets.Next != nil {
37+
for pets.Next != nil && len(*pets.Next) != 0 {
3638
pets, err = curl.Continue(context.Background(), *pets.Next)
3739
if err != nil {
3840
panic(err)
@@ -49,6 +51,37 @@ func main() {
4951
}
5052
}
5153

54+
func create(host string, file string) {
55+
var pet api.Pet
56+
57+
fd, err := os.Open(file)
58+
if err != nil {
59+
panic(err)
60+
}
61+
defer fd.Close()
62+
63+
if err := json.NewDecoder(fd).Decode(&pet); err != nil {
64+
panic(err)
65+
}
66+
67+
cfg, err := config.LoadDefaultConfig(context.Background())
68+
if err != nil {
69+
panic(err)
70+
}
71+
72+
curl := api.NewPetShop(
73+
http.New(awsapi.WithSignatureV4(cfg)),
74+
host,
75+
)
76+
77+
if err := curl.Create(context.Background(), &pet); err != nil {
78+
panic(err)
79+
}
80+
81+
fmt.Printf("==> pet created\n")
82+
output(pet)
83+
}
84+
5285
func output(x any) {
5386
b, _ := json.MarshalIndent(x, "|", " ")
5487
os.Stdout.Write(b)

cmd/server/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package main
33
import (
44
server "net/http"
55

6-
"github.com/fogfish/blueprint-serverless-golang/cmd"
6+
"github.com/fogfish/blueprint-serverless-golang/internal/services/restapi"
77
"github.com/fogfish/gouldian/v2/server/httpd"
88
)
99

1010
func main() {
11-
api := cmd.NewPetShopAPI()
11+
api := restapi.NewPetShopAPI()
1212

1313
server.ListenAndServe(":8080",
1414
httpd.Serve(

0 commit comments

Comments
 (0)