go-zero icon indicating copy to clipboard operation
go-zero copied to clipboard

feat:Goctl can't generate the type of decimal.

Open shaoqingyang opened this issue 2 years ago • 4 comments

As we all know, if using int or float instead of decimal, there may be precision loss, which is fatal for finance. We hope thatdevelopers can enable goct to generate the type of decimal.Decimal to resolve this question.

shaoqingyang avatar Jul 24 '23 08:07 shaoqingyang

The issue can be fixed if you add decimal type to variable type map

1. The decimal type is added to goctl

1.1 You can add decimal type as below,

diff --git a/tools/goctl/api/parser/g4/gen/api/baseparser.go b/tools/goctl/api/parser/g4/gen/api/baseparser.go
index fb34930a..df76777d 100644
--- a/tools/goctl/api/parser/g4/gen/api/baseparser.go
+++ b/tools/goctl/api/parser/g4/gen/api/baseparser.go
@@ -38,6 +38,7 @@ var (
                "string":     holder,
                "byte":       holder,
                "rune":       holder,
+               "decimal":    holder,
        }
 )

1.2 And build goctl with below command,

go build goctl.go

2. How to use decimal type

I use decimal library (https://github.com/shopspring/decimal) to support decimal type

3. Example

3.1 Create greet.api as below

type (		
	Request {	
		Aaa decimal `path:"name"`
	}	
		
	Response {	
		Message string `json:"message"`
	}	
)		
		
service greet-api {		
	@handler GreetHandler	
	get /greet/from/:name(Request) returns (Response)	
}		

3.2 Generate code

go mod tidy		
go get github.com/shopspring/decimal		
goctl api go -api greet.api -dir greet	

the generated files look like:

├── greet │ ├── etc │ │ └── greet-api.yaml // configuration file │ ├── greet.go // main file │ └── internal │ ├── config │ │ └── config.go // configuration definition │ ├── handler │ │ ├── greethandler.go // get/put/post/delete routes are defined here │ │ └── routes.go // routes list │ ├── logic │ │ └── greetlogic.go // request logic can be written here │ ├── svc │ │ └── servicecontext.go // service context, mysql/redis can be passed in here │ └── types │ └── types.go // request/response defined here └── greet.api // api description file

3.3 decimal change for the file type.go

we need import decimal library and change decimal type to decimal.Decimal in file internal/types/types.go

@@ -1,8 +1,12 @@
 // Code generated by goctl. DO NOT EDIT.
 package types
 
+import (
+        "github.com/shopspring/decimal"
+)
+
 type Request struct {
-	Aaa decimal `path:"name"`
+	Aaa decimal.Decimal `path:"name"`
 }

3.4 Update result(not neccessary) in the file internal/logic/greetlogic.go

@@ -25,6 +25,9 @@
 
 func (l *GreetLogic) Greet(req *types.Request) (resp *types.Response, err error) {
 	// todo: add your logic here and delete this line
+	return &types.Response{
+        Message: "Hello go-zero[" + req.Aaa.String() + "]",
+    }, nil
 
- 	return
 }

3.5 Run and check

run the server go run greet.go -f etc/greet-api.yaml

you can check result by curl

curl -i -X GET  http://localhost:8888/greet/from/3000.9999
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Traceparent: 00-ea80cf4d2f7cc21b2ee7e54ba2753cf0-b857e184bb198aee-00
Date: Sun, 03 Dec 2023 03:04:42 GMT
Content-Length: 38

{"message":"Hello go-zero[3000.9999]"}

Thanks,

zzZZzzz888 avatar Dec 03 '23 06:12 zzZZzzz888

You're welcome, this is much better than saving money with the int64 type. Thank you for taking my advice!

shaoqingyang avatar Dec 03 '23 16:12 shaoqingyang

see features #4062

kesonan avatar Apr 10 '24 11:04 kesonan

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


see features #4062

Issues-translate-bot avatar Apr 10 '24 11:04 Issues-translate-bot