diff --git a/README.md b/README.md
index f987f4f..d074a77 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,13 @@
# Freedom DDD Framework
+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/8treenet/freedom/blob/master/LICENSE) [![Go Report Card](https://goreportcard.com/badge/github.com/8treenet/freedom)](https://goreportcard.com/report/github.com/8treenet/freedom)[![GoDoc](https://godoc.org/github.com/8treenet/freedom?status.svg)](https://godoc.org/github.com/8treenet/freedom)
[![GitHub release](https://img.shields.io/github/v/release/8treenet/freedom.svg)](https://github.com/8treenet/freedom/releases)
-###### Freedom是一个基于六边形架构的框架,可以支撑充血的领域模型范式。
+
+###### Freedom 是一个基于六边形架构的框架,可以支撑充血的领域模型范式。
## Overview
+
- 集成 Iris
- HTTP/H2C Server & Client
- 集成普罗米修斯
@@ -18,20 +21,25 @@
- 一级缓存 & 二级缓存 & 防击穿
## 安装
+
```sh
$ go install github.com/8treenet/freedom/freedom@latest
$ freedom version
```
## 脚手架创建项目
+
```sh
$ freedom new-project [project-name]
$ cd [project-name]
+$ go mod tidy
$ go run server/main.go
```
## 脚手架生成增删查改和持久化对象
+
####
+
```sh
# freedom new-po -h 查看更多
$ cd [project-name]
@@ -46,8 +54,9 @@ $ freedom new-po --json ./domain/po/schema.json
## Example
#### [基础教程](https://github.com/8treenet/freedom/blob/master/example/base)
-#### [http2监听和依赖倒置](https://github.com/8treenet/freedom/blob/master/example/http2)
-#### [事务组件&自定义组件&Kafka&领域事件组件](https://github.com/8treenet/freedom/blob/master/example/infra-example)
-#### [一个完整的电商demo,包含CQS、聚合、实体、领域事件、资源库、基础设施](https://github.com/8treenet/freedom/blob/master/example/fshop)
+#### [http2 监听和依赖倒置](https://github.com/8treenet/freedom/blob/master/example/http2)
+
+#### [事务组件&自定义组件&Kafka&领域事件组件](https://github.com/8treenet/freedom/blob/master/example/infra-example)
+#### [一个完整的电商 demo,包含 CQS、聚合、实体、领域事件、资源库、基础设施](https://github.com/8treenet/freedom/blob/master/example/fshop)
diff --git a/README_EN.md b/README_EN.md
index 3e745da..ea17295 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,9 +1,12 @@
# Freedom DDD Framework
+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/8treenet/freedom/blob/master/LICENSE) [![Go Report Card](https://goreportcard.com/badge/github.com/8treenet/freedom)](https://goreportcard.com/report/github.com/8treenet/freedom)[![GoDoc](https://godoc.org/github.com/8treenet/freedom?status.svg)](https://godoc.org/github.com/8treenet/freedom)
+
###### Freedom is a framework based on a hexagonal architecture that supports the congestion domain model paradigm.
## Overview
+
- Integrated Iris v12
- Integrated Prometheus
- Link Tracing
@@ -18,19 +21,23 @@
- Primary Cache & Secondary Cache & Prevent Breakdown
## Install
+
```sh
$ go install github.com/8treenet/freedom/freedom@latest
$ freedom version
```
## Create Project
+
```sh
$ freedom new-project [project-name]
$ cd [project-name]
+$ go mod tidy
$ go run server/main.go
```
## Build Persistent Objects(PO)
+
```sh
# Configurable address and output directory, using 'freedom new-po -h' to see more
$ cd [project-name]
@@ -45,8 +52,11 @@ $ freedom new-po --json ./domain/po/schema.json
## Example
#### [Basic Tutorial](https://github.com/8treenet/freedom/blob/master/example/base)
+
#### [Http2 Listening And Dependency Inversion](https://github.com/8treenet/freedom/blob/master/example/http2)
+
#### [Transaction Components And Custom Components](https://github.com/8treenet/freedom/blob/master/example/infra-example)
+
#### [Message Events And Domain Events](https://github.com/8treenet/freedom/blob/master/example/event-example)
-#### [Electronic Demo(Contains CQS、Aggregation、entity、Domain Events、Repository、Infrastructure)](https://github.com/8treenet/freedom/blob/master/example/fshop)
+#### [Electronic Demo(Contains CQS、Aggregation、entity、Domain Events、Repository、Infrastructure)](https://github.com/8treenet/freedom/blob/master/example/fshop)
diff --git a/example/base/adapter/controller/default.go b/example/base/adapter/controller/default.go
index 07ac3d9..f3c1d67 100644
--- a/example/base/adapter/controller/default.go
+++ b/example/base/adapter/controller/default.go
@@ -1,7 +1,6 @@
package controller
import (
- "fmt"
"io"
"os"
@@ -38,6 +37,7 @@ type Default struct {
// Get handles the GET: / route.
func (c *Default) Get() freedom.Result {
+ //curl http://127.0.0.1:8000
c.Worker.Logger().Info("I'm Controller")
remote := c.Sev.RemoteInfo()
return &infra.JSONResponse{Object: remote}
@@ -45,6 +45,7 @@ func (c *Default) Get() freedom.Result {
// GetHello handles the GET: /hello route.
func (c *Default) GetHello() string {
+ //curl http://127.0.0.1:8000/hello
field := freedom.LogFields{
"framework": "freedom",
"like": "DDD",
@@ -64,11 +65,13 @@ func (c *Default) GetHello() string {
// PutHello handles the PUT: /hello route.
func (c *Default) PutHello() freedom.Result {
+ //curl -X PUT http://127.0.0.1:8000/hello
return &infra.JSONResponse{Object: "putHello"}
}
// PostHello handles the POST: /hello route.
func (c *Default) PostHello() freedom.Result {
+ //curl -X POST -d '{"userName":"freedom","userPassword":"freedom"}' http://127.0.0.1:8000/hello
var postJSONData struct {
UserName string `json:"userName" validate:"required"`
UserPassword string `json:"userPassword" validate:"required"`
@@ -77,26 +80,55 @@ func (c *Default) PostHello() freedom.Result {
return &infra.JSONResponse{Error: err}
}
- return &infra.JSONResponse{Object: "postHello"}
+ return &infra.JSONResponse{Object: postJSONData}
}
+// PutHello handles the DELETE: /hello route.
+func (c *Default) DeleteHello() freedom.Result {
+ //curl -X DELETE http://127.0.0.1:8000/hello
+ return &infra.JSONResponse{Object: "deleteHello"}
+}
+
+/* Can use more than one, the factory will make sure
+that the correct http methods are being registered for each route
+for this controller, uncomment these if you want:
+ func (c *Default) ConnectHello() {}
+ func (c *Default) HeadHello() {}
+ func (c *Default) PatchHello() {}
+ func (c *Default) OptionsHello() {}
+ func (c *Default) TraceHello() {}
+*/
+
// BeforeActivation .
func (c *Default) BeforeActivation(b freedom.BeforeActivation) {
- b.Handle("ANY", "/custom", "CustomHello")
- //b.Handle("GET", "/custom", "CustomHello")
- //b.Handle("PUT", "/custom", "CustomHello")
- //b.Handle("POST", "/custom", "CustomHello")
+ b.Handle("GET", "/customPath/{id:int64}/{uid:int}/{username:string}", "CustomPath")
+ b.Handle("ANY", "/custom", "Custom")
+ //b.Handle("GET", "/custom", "Custom")
+ //b.Handle("PUT", "/custom", "Custom")
+ //b.Handle("POST", "/custom", "Custom")
+ //b.Handle("DELETE", "/custom", "Custom")
+}
+
+// CustomPath handles the GET: /customPath/{id:int64}/{uid:int}/{username:string} route.
+func (c *Default) CustomPath(id int64, uid int, username string) freedom.Result {
+ //curl http://127.0.0.1:8000/customPath/1/2/freedom
+ return &infra.JSONResponse{Object: map[string]interface{}{"id": id, "uid": uid, "username": username}}
}
-// CustomHello handles the POST: /hello route.
-func (c *Default) CustomHello() freedom.Result {
+// Custom handles the ANY: /custom route.
+func (c *Default) Custom() freedom.Result {
+ //curl http://127.0.0.1:8000/custom
+ //curl -X PUT http://127.0.0.1:8000/custom
+ //curl -X DELETE http://127.0.0.1:8000/custom
+ //curl -X POST http://127.0.0.1:8000/custom
method := c.Worker.IrisContext().Request().Method
c.Worker.Logger().Info("CustomHello", freedom.LogFields{"method": method})
- return &infra.JSONResponse{Object: method + "CustomHello"}
+ return &infra.JSONResponse{Object: method + "/Custom"}
}
// GetUserBy handles the GET: /user/{username:string} route.
func (c *Default) GetUserBy(username string) freedom.Result {
+ //curl 'http://127.0.0.1:8000/user/freedom?token=ftoken123&id=1&ip=192&ip=168&ip=1&ip=1'
var query struct {
Token string `url:"token" validate:"required"`
ID int64 `url:"id" validate:"required"`
@@ -120,6 +152,7 @@ func (c *Default) GetUserBy(username string) freedom.Result {
// GetAgeByUserBy handles the GET: /age/{age:int}/user/{user:string} route.
func (c *Default) GetAgeByUserBy(age int, user string) freedom.Result {
+ //curl http://127.0.0.1:8000/age/20/user/freedom
var result struct {
User string
Age int
@@ -132,6 +165,7 @@ func (c *Default) GetAgeByUserBy(age int, user string) freedom.Result {
// PostForm handles the Post: /form route.
func (c *Default) PostForm() freedom.Result {
+ //curl -X POST --data "userName=freedom&mail=freedom@freedom.com&myData=data1&myData=data2" http://127.0.0.1:8000/form
var visitor struct {
UserName string `form:"userName" validate:"required"`
Mail string `form:"mail" validate:"required"`
@@ -147,6 +181,7 @@ func (c *Default) PostForm() freedom.Result {
// PostFile handles the Post: /file route.
func (c *Default) PostFile() freedom.Result {
+ //curl -X POST -F "file=@example/base/adapter/controller/default.go" http://127.0.0.1:8000/file
file, info, err := c.Worker.IrisContext().FormFile("file")
if err != nil {
return &infra.JSONResponse{Error: err}
@@ -159,8 +194,7 @@ func (c *Default) PostFile() freedom.Result {
return &infra.JSONResponse{Error: err}
}
defer out.Close()
- fmt.Println("file:", os.TempDir()+fname)
_, err = io.Copy(out, file)
- return &infra.JSONResponse{Error: err}
+ return &infra.JSONResponse{Error: err, Object: os.TempDir() + fname}
}
diff --git a/freedom/cmd/version.go b/freedom/cmd/version.go
index a9cb8c9..455aacc 100644
--- a/freedom/cmd/version.go
+++ b/freedom/cmd/version.go
@@ -7,7 +7,7 @@ import (
)
const (
- versionNum = "v1.9.2"
+ versionNum = "v1.9.3"
)
var (
diff --git a/freedom/template/project/controllers.go b/freedom/template/project/controllers.go
index 492c80f..55b68d7 100644
--- a/freedom/template/project/controllers.go
+++ b/freedom/template/project/controllers.go
@@ -12,6 +12,8 @@ func controllerTemplate() string {
package controller
import (
+ "io"
+ "os"
"github.com/8treenet/freedom"
"{{.PackagePath}}/domain"
"{{.PackagePath}}/infra"
@@ -32,6 +34,7 @@ func controllerTemplate() string {
//Get handles the GET: / route.
func (c *Default) Get() freedom.Result {
+ //curl http://127.0.0.1:8000
c.Worker.Logger().Info("I'm Controller")
remote := c.Sev.RemoteInfo()
return &infra.JSONResponse{Object: remote}
@@ -39,6 +42,7 @@ func controllerTemplate() string {
//GetHello handles the GET: /hello route.
func (c *Default) GetHello() string {
+ //curl http://127.0.0.1:8000/hello
field := freedom.LogFields{
"framework": "freedom",
"like": "DDD",
@@ -58,11 +62,13 @@ func controllerTemplate() string {
//PutHello handles the PUT: /hello route.
func (c *Default) PutHello() freedom.Result {
+ //curl -X PUT http://127.0.0.1:8000/hello
return &infra.JSONResponse{Object: "putHello"}
}
// PostHello handles the POST: /hello route.
func (c *Default) PostHello() freedom.Result {
+ //curl -X POST -d '{"userName":"freedom","userPassword":"freedom"}' http://127.0.0.1:8000/hello
var postJSONData struct {
UserName string $$wavejson:"userName" validate:"required"$$wave
UserPassword string $$wavejson:"userPassword" validate:"required"$$wave
@@ -71,26 +77,55 @@ func controllerTemplate() string {
return &infra.JSONResponse{Error: err}
}
- return &infra.JSONResponse{Object: "postHello"}
+ return &infra.JSONResponse{Object: postJSONData}
}
+ // PutHello handles the DELETE: /hello route.
+ func (c *Default) DeleteHello() freedom.Result {
+ //curl -X DELETE http://127.0.0.1:8000/hello
+ return &infra.JSONResponse{Object: "deleteHello"}
+ }
+
+ /* Can use more than one, the factory will make sure
+ that the correct http methods are being registered for each route
+ for this controller, uncomment these if you want:
+ func (c *Default) ConnectHello() {}
+ func (c *Default) HeadHello() {}
+ func (c *Default) PatchHello() {}
+ func (c *Default) OptionsHello() {}
+ func (c *Default) TraceHello() {}
+ */
+
// BeforeActivation .
func (c *Default) BeforeActivation(b freedom.BeforeActivation) {
- b.Handle("ANY", "/custom", "CustomHello")
- //b.Handle("GET", "/custom", "CustomHello")
- //b.Handle("PUT", "/custom", "CustomHello")
- //b.Handle("POST", "/custom", "CustomHello")
+ b.Handle("GET", "/customPath/{id:int64}/{uid:int}/{username:string}", "CustomPath")
+ b.Handle("ANY", "/custom", "Custom")
+ //b.Handle("GET", "/custom", "Custom")
+ //b.Handle("PUT", "/custom", "Custom")
+ //b.Handle("POST", "/custom", "Custom")
+ //b.Handle("DELETE", "/custom", "Custom")
+ }
+
+ // CustomPath handles the GET: /customPath/{id:int64}/{uid:int}/{username:string} route.
+ func (c *Default) CustomPath(id int64, uid int, username string) freedom.Result {
+ //curl http://127.0.0.1:8000/customPath/1/2/freedom
+ return &infra.JSONResponse{Object: map[string]interface{}{"id": id, "uid": uid, "username": username}}
}
- //CustomHello handles the POST: /hello route.
- func (c *Default) CustomHello() freedom.Result {
+ // Custom handles the ANY: /custom route.
+ func (c *Default) Custom() freedom.Result {
+ //curl http://127.0.0.1:8000/custom
+ //curl -X PUT http://127.0.0.1:8000/custom
+ //curl -X DELETE http://127.0.0.1:8000/custom
+ //curl -X POST http://127.0.0.1:8000/custom
method := c.Worker.IrisContext().Request().Method
c.Worker.Logger().Info("CustomHello", freedom.LogFields{"method": method})
- return &infra.JSONResponse{Object: method + "CustomHello"}
+ return &infra.JSONResponse{Object: method + "/Custom"}
}
- //GetUserBy handles the GET: /user/{username:string}?token=ftoken123&id=1&ip=192&ip=168&ip=1&ip=1 route.
+ //GetUserBy handles the GET: /user/{username:string} route.
func (c *Default) GetUserBy(username string) freedom.Result {
+ //curl 'http://127.0.0.1:8000/user/freedom?token=ftoken123&id=1&ip=192&ip=168&ip=1&ip=1'
var query struct {
/*
Equal
@@ -120,6 +155,7 @@ func controllerTemplate() string {
//GetAgeByUserBy handles the GET: /age/{age:int}/user/{user:string} route.
func (c *Default) GetAgeByUserBy(age int, user string) freedom.Result {
+ //curl http://127.0.0.1:8000/age/20/user/freedom
var result struct {
User string
Age int
@@ -129,6 +165,42 @@ func controllerTemplate() string {
return &infra.JSONResponse{Object: result}
}
+
+ // PostForm handles the Post: /form route.
+ func (c *Default) PostForm() freedom.Result {
+ //curl -X POST --data "userName=freedom&mail=freedom@freedom.com&myData=data1&myData=data2" http://127.0.0.1:8000/form
+ var visitor struct {
+ UserName string $$waveform:"userName" validate:"required"$$wave
+ Mail string $$waveform:"mail" validate:"required"$$wave
+ Data []string $$waveform:"myData" validate:"required"$$wave
+ }
+ err := c.Request.ReadForm(&visitor, true)
+ if err != nil {
+ return &infra.JSONResponse{Error: err}
+ }
+ c.Worker.Logger().Infof("%d, %s, %s, %v", c.Worker.IrisContext().Request().ContentLength, visitor.UserName, visitor.Mail, visitor.Data)
+ return &infra.JSONResponse{Object: visitor}
+ }
+
+ // PostFile handles the Post: /file route.
+ func (c *Default) PostFile() freedom.Result {
+ //curl -X POST -F "file=@example/base/adapter/controller/default.go" http://127.0.0.1:8000/file
+ file, info, err := c.Worker.IrisContext().FormFile("file")
+ if err != nil {
+ return &infra.JSONResponse{Error: err}
+ }
+
+ defer file.Close()
+ fname := info.Filename
+ out, err := os.OpenFile(os.TempDir()+fname, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
+ if err != nil {
+ return &infra.JSONResponse{Error: err}
+ }
+ defer out.Close()
+ _, err = io.Copy(out, file)
+
+ return &infra.JSONResponse{Error: err, Object: os.TempDir() + fname}
+ }
`
result = strings.ReplaceAll(result, "$$wave", "`")