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

chore(*): best practice for api definition #5

Merged
merged 5 commits into from
Apr 28, 2020

Conversation

supereagle
Copy link
Member

What this PR does / why we need it:

Best practice for api definition for projects using Nirvana framework.

Which issue(s) this PR is related to (optional, link to 3rd issue(s)):

Fixes #

Reference to #

Special notes for your reviewer:

/cc @your-reviewer

Release note:

NONE

@caicloud-bot caicloud-bot added release-note-none Denotes a PR that doesn't merit a release note. caicloud-cla: yes Indicates the PR's author has not signed the Caicloud CLA. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 22, 2020
@supereagle
Copy link
Member Author

Wait for reviews

/hold

@caicloud-bot caicloud-bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 22, 2020
Copy link
Contributor

@lichuan0620 lichuan0620 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so minor issues with the position of middlewares

the major issue is, we wrote so much that this repo essentially becomes nirvana-demo instead of nirvana-practice

apis.Install(config)
config := nirvana.NewDefaultConfig().Configure(
nirvana.Port(httpPort),
reqlog.Default(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enabling reqlog at base level might not be a good idea; best adding it at /api so that no log will be printed for /healthz and /metircs

Copy link
Member Author

@supereagle supereagle Apr 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe reqlog can only be applied to base level. If we want to add it to /api level, we need to write a log middleware by ourselves.

Please confirm @iawia002

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm standing with @lichuan0620, we don't need to log every request such as /healthz and /metrics, it's useless. We recommend logging only helpful request such as /api/*

Copy link
Member Author

@supereagle supereagle Apr 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have used the log middleware in go-common.

return definition.Descriptor{
Description: "v1alpha1 API",
Path: "/v1alpha1",
Consumes: []string{definition.MIMEJSON},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless not all APIs are JSON, those should be added only at /api level

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comments to illustrate that other content types can be added if necessary.

return nil, errors.ErrorNotImplemented.Error()
}

func ListProducts(ctx context.Context, options *v1.ListOptions) (*api.ProductsList, error) {
return nil, errors.ErrorNotImplemented.Error()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that all incomplete functions have been implemented. Doesn't that defeat the purpose of this repo?

nirvana-practice is a public repo meant for helping people practice writing web server with Nirvana. If we finish everything, then they have nothing to practice...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have removed the implementation.

@@ -0,0 +1,50 @@
package handlers
Copy link
Member

@ddysher ddysher Apr 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we moving all business logic to pkg/apis?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Prefer in pkg/handlers

Copy link
Member

@ddysher ddysher Apr 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

we did discuss this before, the proposed (slightly modified) structure is

.                                   #
├── Gopkg.toml                      #
├── Makefile                        #
├── README.md                       # 
├── apis                            # 存放 apidocs (swagger json)
│   ├── api.v1.json                 #
│   └── api.v2.json                 #
├── bin                             # 存放编译后的二进制文件
│   └── nirvana-myproject           #
├── build                           # 存放 Dockerfile
│   └── nirvana-myproject           #
│       └── Dockerfile              #
├── cmd                             # 存放项目的启动命令
│   └── nirvana-myproject           #
│       └── main.go                 #
├── nirvana.yaml                    #
├── pkg                             # 存放 api 需要用到的结构体与相应的 converters, 按版本区分
│   ├── apis                        #
│   │   └── v1                      #
│   │       ├── converters          #
│   │       │   └── converters.go   #
│   │       └── types.go            #
│   │       ├── descriptors          #
│   │           ├── descriptors.go      #
│   │           └── message.go          # 对应 message 业务逻辑的 API 定义
│   ├── filters                     # 存放 HTTP Request 过滤器
│   │   └── filter.go               #
│   ├── handler                     # 存放 API 需要用到的逻辑处理
│   │   └── message.go              #
│   ├── middlewares                 # 存放中间件
│   │   └── middlewares.go          #
│   ├── modifiers                   # 存放 Definition 修改器
│   │   └── modifiers.go            #
│   └── version                     # 项目版本信息目录
│       └── version.go              #
└── vendor                          #

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a unified project structure definitely makes it easier to read new projects

3.0 might be a good chance to reinforce this idea since many of us will be migrating our repos for COS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will enforce the unification of projects' structure in v3.0.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not the standard structure generated by nirvana init?

Nope, see #5 (comment). The question is do we need to discuss the structure again?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, handler/middlewares/modifiers should all be moved into pkg/apis/v1 (e.g. you can't say for sure that modifiers won't touch any v1 data structure).

But this makes the code hard to reason about. I'd vote for current structure and keep it as is. The pkg/apis is only used for user-facing structures and routes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this makes the code hard to reason about. I'd vote for current structure and keep it as is. The pkg/apis is only used for user-facing structures and routes.

Agree

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. handler or handlers?
  2. Do we need to separate handler/middlewares/modifiers into different versions like v1 and v2?
  1. handler
  2. no separation inside handler/middlewares/modifiers

Agreed?

Copy link
Member Author

@supereagle supereagle Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can move to caicloud/nirvana#318 for more discussions instead of here.

@supereagle
Copy link
Member Author

Have fixed the comments. @lichuan0620 @iawia002 @ddysher PTAL

@supereagle
Copy link
Member Author

/hold cancel

@caicloud-bot caicloud-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 27, 2020
Copy link
Member Author

@supereagle supereagle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️Highlight the key points.

Description: "APIs",
Path: "/api",
Middlewares: []def.Middleware{
middleware.Reqlog(log.DefaultLogger()),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the log middleware in go-common

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go-common is a private repo and this is a public repo

Copy link
Member Author

@supereagle supereagle Apr 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have copy the log middleware from go-common to this repo, PTAL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can just change go-common to a public repo?

My concern is that once we start advocating this practice, then people will start to use this copied version of log package, instead of the one in go-common, making it difficult to maintain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can just change go-common to a public repo?

I don't like that idea, at least not now. It'll make things more complicated.

Instead, why don't we add some of the more mature features from go-common to Nirvana? One thing we should definitely think about is to implement some built-in middleware in Nirvana. reqlog is obvious. The metrics plugin would also use a middleware implementation (you don't usually want request metrics on the /metrics API).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM, we can move the plugins into nirvana core, or create another dedicated nirvana-plugins repo.

go.mod Outdated
github.com/caicloud/go-common v0.3.5
github.com/caicloud/nirvana v0.2.4
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dependencies require go-common v0.3.5+ and nirvana v0.2.4+.

Comment on lines +15 to +18
- name: v1alpha1
description: The v1alpha1 version of this project
rules:
- prefix: /api/v1alpha1/
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add more versions if necessary.

{
Path: "/customers",
Description: "Customer API",
Tags: []string{"customer"},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tags to classify APIs.

@ddysher
Copy link
Member

ddysher commented Apr 28, 2020

This seems to be different from nirvana template project,

  • descriptors should be put under pkg/, instead of pkg/apis
  • a top-level descriptor.go
  • maybe some others

Personally, structure nirvana template project makes more sense to me.

/cc @iawia002

@iawia002
Copy link

Yes, this is different from nirvana template project cause this project is generated by nirvana init, and the template in nirvana init hasn't synced with the nirvana template project repo.

@ddysher
Copy link
Member

ddysher commented Apr 28, 2020

We need a single source of truth; once this is finalized, we need to converge all these tools/repos.

  • nirvana init is the single source of truth
  • template repo is created from nirvana init (with docs pointing to the fact that it's generated from nirvana init)
  • practice should be forked from template repo

All future changes should go to nirvana init.

An alternative might be to merge nirvana init and template repo.

@iawia002 make the call?

@iawia002
Copy link

We need a single source of truth; once this is finalized, we need to converge all these tools/repos.

  • nirvana init is the single source of truth

I have submitted an issue about this: caicloud/nirvana#304

  • template repo is created from nirvana init (with docs pointing to the fact that it's generated from nirvana init)
    ..
    An alternative might be to merge nirvana init and template repo.

Yes, I think we can deprecate nirvana-template-project repo, all nirvana projects can be easily generated by nirvana init xxx.

@ddysher
Copy link
Member

ddysher commented Apr 28, 2020

SGTM

Yes, I think we can deprecate nirvana-template-project repo, all nirvana projects can be easily generated by nirvana init xxx.

@supereagle
Copy link
Member Author

Yes, I think we can deprecate nirvana-template-project repo, all nirvana projects can be easily generated by nirvana init xxx.

SGTM

@lichuan0620
Copy link
Contributor

/lgtm

@caicloud-bot caicloud-bot added the lgtm Indicates that a PR is ready to be merged. label Apr 28, 2020
@caicloud-bot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lichuan0620

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@caicloud-bot caicloud-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 28, 2020
@caicloud-bot caicloud-bot merged commit 7a6f3e7 into caicloud:master Apr 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. caicloud-cla: yes Indicates the PR's author has not signed the Caicloud CLA. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants