Skip to content

Commit

Permalink
Update docs to use repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
System-Glitch committed Apr 22, 2024
1 parent 5681fb9 commit 049f956
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 41 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 Jérémy LAMBERT (SystemGlitch)
Copyright (c) 2024 Jérémy LAMBERT (SystemGlitch)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
77 changes: 37 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,41 @@
go get goyave.dev/filter
```

First, add the necessary query validation to your index route:
```go
router.GlobalMiddleware(&parse.Middleware{}) // Don't forget the parse middleware!
router.Get("/users", user.Index).ValidateQuery(filter.Validation)
```

Then implement your controller handler:
Then, create a new method in your repository and service:
```go
// database/repository/user.go
import "goyave.dev/filter"

//...

func (ctrl *UserController) Index(response *goyave.Response, request *goyave.Request) {
var users []*model.User
paginator, tx := filter.Scope(ctrl.DB(), filter.NewRequest(request.Query), &users)
if response.WriteDBError(tx.Error) {
func (r *User) Paginate(ctx context.Context, request *filter.Request) (*database.Paginator[*model.User], error) {
users := []*model.User{}
paginator, err := filter.Scope(session.DB(ctx, r.DB), request, &users)
return paginator, errors.New(err)
}
```
```go
// service/user/user.go
func (s *Service) Paginate(ctx context.Context, request *filter.Request) (*database.PaginatorDTO[*dto.User], error) {
paginator, err := s.repository.Paginate(ctx, request)
return typeutil.MustConvert[*database.PaginatorDTO[*dto.User]](paginator), errors.New(err)
}
```
From your controller, use `filter.NewRequest()` with the request's query to generate the filter request DTO:
```go
// http/controller/user/user.go
func (ctrl *Controller) Index(response *goyave.Response, request *goyave.Request) {
paginator, err := ctrl.userService.Paginate(request.Context(), filter.NewRequest(request.Query))
if response.WriteDBError(err) {
return
}

// Convert to DTO and write response
dto := typeutil.MustConvert[database.PaginatorDTO[dto.User]](paginator)
response.JSON(http.StatusOK, dto)
response.JSON(http.StatusOK, paginator)
}
```

Expand All @@ -44,13 +58,9 @@ And **that's it**! Now your front-end can add query parameters to filter as it w
You can also find records without paginating using `ScopeUnpaginated()`:
```go
var users []*model.User
tx := filter.ScopeUnpaginated(ctrl.DB(), filter.NewRequest(request.Query), &users)
if response.WriteDBError(tx.Error) {
return
}
dto := typeutil.MustConvert[database.PaginatorDTO[dto.User]](paginator)
response.JSON(http.StatusOK, dto)
tx := filter.ScopeUnpaginated(session.DB(ctx, r.DB), request, &users)
```
*Note: `ScopeUnpaginated()` returns a `*gorm.DB`, not directly an error. To check for errors, use `tx.Error`.*

### Settings

Expand Down Expand Up @@ -93,7 +103,7 @@ settings := &filter.Settings[*model.User]{
},
}
results := []*model.User{}
paginator, tx := settings.Scope(ctrl.DB(), filter.NewRequest(request.Query), &results)
paginator, err := settings.Scope(session.DB(ctx, r.DB), request, &results)
```

### Filter
Expand Down Expand Up @@ -196,7 +206,7 @@ You can join multiple relations:
### Pagination

Internally, `goyave.dev/filter` uses [Goyave's `Paginator`](https://goyave.dev/guide/basics/database.html#pagination).
Internally, `goyave.dev/filter` uses [Goyave's `Paginator`](https://goyave.dev/basics/database.html#pagination).

> ?page=**1**&per_page=**10**
Expand Down Expand Up @@ -298,15 +308,9 @@ type MyModel struct{

If you want to add static conditions (not automatically defined by the library), it is advised to group them like so:
```go
users := []model.User{}
db := ctrl.DB()
db = db.Where(db.Session(&gorm.Session{NewDB: true}).Where("username LIKE ?", "%Miss%").Or("username LIKE ?", "%Ms.%"))
paginator, tx := filter.Scope(db, filter.NewRequest(request.Query), &users)
if response.WriteDBError(tx.Error) {
return
}
dto := typeutil.MustConvert[database.PaginatorDTO[dto.User]](paginator)
response.JSON(http.StatusOK, dto)
users := []*model.User{}
db = session.DB(ctx, r.DB).Where(r.DB.Where("username LIKE ?", "%Miss%").Or("username LIKE ?", "%Ms.%"))
paginator, err := filter.Scope(db, request, &users)
```

### Custom operators
Expand Down Expand Up @@ -420,19 +424,12 @@ func convertArgsToSafeTypeArray[T argType](args []string, dataType filter.DataTy
Manual joins are supported and won't clash with joins that are automatically generated by the library. That means that if needed, you can write something like described in the following piece of code.

```go
func (ctrl *UserController) Index(response *goyave.Response, request *goyave.Request) {
// database/repository/user.go
func (r *User) Paginate(ctx context.Context, request *filter.Request) (*database.Paginator[*model.User], error) {
var users []*model.User

db := ctrl.DB().Joins("Relation")

paginator, tx := filter.Scope(db, filter.NewRequest(request.Query), &users)
if response.WriteDBError(tx.Error) {
return
}

// Convert to DTO and write response
dto := typeutil.MustConvert[database.PaginatorDTO[dto.User]](paginator)
response.JSON(http.StatusOK, dto)
db := session.DB(ctx, r.DB).Joins("Relation")
paginator, err := filter.Scope(db, request, &users)
return paginator, errors.New(err)
}
```

Expand All @@ -454,9 +451,9 @@ func IndexRequest(r *goyave.Request) v.RuleSet {

`*filter.Settings` now takes a generic parameter: a pointer to the target model. The slice given to the `Scope` method is expected to be a pointer to a slice of the same type.
```go
settings := &Settings[*model.User]{}
settings := &filter.Settings[*model.User]{}
```

## License

`goyave.dev/filter` is MIT Licensed. Copyright (c) 2023 Jérémy LAMBERT (SystemGlitch)
`goyave.dev/filter` is MIT Licensed. Copyright (c) 2024 Jérémy LAMBERT (SystemGlitch)

0 comments on commit 049f956

Please sign in to comment.