go-gorm / go-gorm/cli

Feedback + some issues I faced with an idiomatic structure/ non layered structure

Open
#40 0 comments 1 reaction 1 assignee Claimed by @jinzhu View on GitHub
Dominant language
Go
Stars
108
Forks
15
PR merge metrics
No merged PRs in 30d

Description

## Describe the feature

First of all, Thanks a lot working on Gorm from v1 to cli generators. Really enjoyed the dev process, preloads and docs.

### 1. Idiomatic folder structure

As the layered architecture considered not quite idiomatic in Go, I tried to create some usecase / modular way to keep the handler, model, repository together in each case, instead of put all models, all repositories, all filters as layers.

```go
// 💡 Example: a simple bookshelf

├── app
│ ├── book
│ │ ├── bookrepo # 💡generated with gorm-cli via the interface in book/repository.go
│ │ │ └── repository.go
│ │ ├── form_util.go
│ │ ├── handler.go
│ │ └── repository.go
│ └── router
│ └── router.go
```

In the beginning I tried to put form and model inside app/book but due to circular dependencies I had to move model(entities) / form outside folders. It may make sense as shared preloads. I used bookrepo as It can have more than 1 repo/ repo interfaces, inside that module. So, repositories auto generate per usecase/ module. (Project can have duplicated repo func but all autogenerated and isolated to the usecase folder/ module.

About filters, first issue I got is that it uses same Struct name and can't place same place together with Model.

My suggestion: Assume we use modular usecase folder isolation; handler.go, model.go, repository.go together,

1. Use `filename_gen.go` instead of separate "generated" folder for generated files. And all in together. Use `IRepo` for interface and Repo for Struct.
2. Allow generate repo functions from an interface + allow add extra manually to same repo when auto generated not enough: in the same place.

This way code can kept more idiomatic and groups related files by usecase/ module, instead of layers.

### 2. Formatting

I used following for bookshelf CRUD.

1. We can't use same model name as the variable name. ex `@book.Title` . Used `data` instead `book`
2. Most IDEs underlines comments when not started with same func name. `ListBooks` comment should start with `// ListBooks ...`. As I understood, this breaks the generated SQL
3. Queries in comment can't divide into multiple lines sometimes. Example `VALUES` on insert. When the table getting bigger this might be an issue. Is this a design choice/ constrain or I'm wrong here?
4. Suggestion: If the cli can generate multiple files(1 per each RepoInterface) from 1 Query file, we can keep all interface in 1 file and generate multiple repo files per interface.

```go
//go:generate gorm gen -i repository.go::IBookRepo -o bookrepo
type IBookRepo interface {
// SELECT * FROM books LIMIT @limit OFFSET @offset
ListBooks(ctx context.Context, limit int64, offset int64) (model.Books, error)

// INSERT INTO books (id, created_at, updated_at, title, author, published_date, image_url, description) VALUES (@data.ID, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, @data.Title, @data.Author, @data.PublishedDate, @data.ImageURL, @data.Description)
// RETURNING *
CreateBook(ctx context.Context, data *model.Book) (*model.Book, error)

// SELECT * FROM books WHERE id = @id
ReadBook(ctx context.Context, id uuid.UUID) (*model.Book, error)

// UPDATE books
// SET updated_at=CURRENT_TIMESTAMP, title=@data.Title, author=@data.Author, published_date=@data.PublishedDate, image_url=@data.ImageURL, description=@data.Description
// WHERE id = @data.ID
// RETURNING *
UpdateBook(ctx context.Context, data *model.Book) (*model.Book, error)

// DELETE FROM books WHERE id = @id
// RETURNING true
DeleteBook(ctx context.Context, id uuid.UUID) (bool, error)
}
```

Thanks again for your work.

## Motivation

1. Keep the codebase not layered and keep more idiomatic.
2. Understand code organization and best practices while using GORM CLI.
3. Understand formatting query comments into multiple lines

## Related Issues

https://github.com/learning-cloud-native-go/myapp/tree/main/app/book (Not a direct issue) Just wanna understand anything missing or can improve

Thanks

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.