Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add zero-api-sepc.md #2

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 419 additions & 0 deletions ast/ast.go

Large diffs are not rendered by default.

142 changes: 142 additions & 0 deletions cmd/apifmt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package main

import (
"errors"
"flag"
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"

"github.com/zeromicro/zero-api/format"
)

var (
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
)

func usage() {
fmt.Fprint(os.Stderr, "usage: apifmt [flags] [path ...]\n")
flag.PrintDefaults()
}

func report(err error) {
fmt.Println(err)
os.Exit(2)
}

func processFile(fileName string, info fs.FileInfo, in io.Reader, out io.Writer) error {
if in == nil {
var err error
in, err = os.Open(fileName)
if err != nil {
return err
}
}

src, err := ioutil.ReadAll(in)
if err != nil {
return err
}

res, err := format.Source(src, fileName)
if err != nil {
return err
}

if *write {
_, err := out.Write(res)
return err
}
// write to file
perm := info.Mode().Perm()
backName, err := backupFile(fileName+".", src, perm)
if err != nil {
return err
}

err = os.WriteFile(fileName, res, perm)
if err != nil {
_ = os.Rename(backName, fileName)
return err
}

err = os.Remove(backName)
return err
}

const chmodSupported = runtime.GOOS != "windows"

func backupFile(filename string, data []byte, perm fs.FileMode) (string, error) {
f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename))
if err != nil {
return "", err
}
backname := f.Name()
if chmodSupported {
err := f.Chmod(perm)
if err != nil {
_ = f.Close()
_ = os.Remove(backname)
return backname, err
}
}

_, err = f.Write(data)
if err1 := f.Close(); err1 != nil {
err = err1
}
return backname, err
}

func main() {
flag.Usage = usage
flag.Parse()

args := flag.Args()
if len(args) == 0 {
if *write {
report(errors.New("error: cannot use -w with standard input"))
return
}
// *write not support standard input, so fs.FileInfo can be nil.
if err := processFile("<standard input>", nil, os.Stdin, os.Stdout); err != nil {
report(err)
}
return
}

for _, path := range args {
walkSubDir := strings.HasSuffix(path, "/...")
if walkSubDir {
path = path[:len(path)-1]
}
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else if d.IsDir() {
if !walkSubDir {
return filepath.SkipDir
}
} else {
ext := filepath.Ext(path)
if ext != ".api" {
return nil
}

info, err := d.Info()
if err != nil {
return err
}
if err := processFile(path, info, nil, os.Stdout); err != nil {
report(err)
}
}
return err
})
}
}
60 changes: 60 additions & 0 deletions doc/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 1. req resp 的定义
背景: 目前我们 req 与 resp 的定义是使用 go struct 的定义规则,但是存在的问题是 json key 是使用 tag 中的定义,
这样非 go 相关的同学可能不太熟悉这个规则,同时这个 key 编写起来太麻烦了,需要定义2边,一次 field,一次 tag 中。

```go
type User {
Id int64 `json:"id"`
}

type User {
id int64
}
```

# 2. resp 相关定义
目前我们的 response 可以用过 httpx.Ok 进行返回,也有部分会改下 response 的方式,例如会返回 **{"code": 0, "data": {}}**
但是这种格式无法在 API 中提现出来。


# 3. api 中 error 相关的返回。
目前针对 API 的 error 无法体现出来。
post /user/login(req) returns (resp)
返回的错误码,错误格式,错误描述等信息无法通过 API 体现

同时一种可能的格式
```api
post /foo(req) returns (resp, error)
```

# 4. type 是否需要支持 interface{} any
部分同学在使用的过程中,想要通过 interface{} 或者 any 表示任意对象

这种在 zero-api 中是不被支持的,我们推荐使用严格标准的表示方法,将具体的信息表示出来。


# 5. handler 同名支持

```api
@handler foo
get /foo(req)

@handler foo
post /foo(req)


// one
@handler foo
get|post /foo(req)


@handler foo
get /foo(req)
post /foo(req)

```
这种不会支持,建议直接定义不同的 handler 自行处理

# 6. type 定义 group
refer: https://github.com/zeromicro/go-zero/issues/1854

Loading