-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added basic support for foreign keys, updated docs, dehardcoding
- Loading branch information
Showing
28 changed files
with
958 additions
and
276 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,72 @@ | ||
# Serializers | ||
|
||
Nothing here yet... | ||
Serializers in GRF are responsible for translation of data between the database and the API. They control which fields are accepted in the payload, which are served in the response, and how they are formatted. The best way to understand how serializers work is to see them in action. | ||
|
||
```go | ||
type Serializer interface { | ||
// This function is called when transforming the request payload into an internal value | ||
// that will be later passed to QueryDriver (for example GORM) for processing. | ||
ToInternalValue(map[string]any, *gin.Context) (models.InternalValue, error) | ||
|
||
// This function transforms data obtained from the QueryDriver into a response payload, that | ||
// will be then marshalled into JSON and sent to the client. | ||
ToRepresentation(models.InternalValue, *gin.Context) (Representation, error) | ||
} | ||
``` | ||
|
||
## ModelSerializer | ||
|
||
`ModelSerializer` is the workhorse of GRF. It can be created with `serializers.NewModelSerializer[Model]()`. By default such serializer will include all struct fields (there's also `NewEmptyModelSerializer[Model]()` that will not include any fields). | ||
|
||
|
||
### Using existing fields in ModelSerializer | ||
|
||
You can select which existing fields should be included in the response by using the `WithModelFields` method. | ||
|
||
```go | ||
serializer := serializers.NewModelSerializer[Model]().WithModelFields("field1", "field2") | ||
``` | ||
|
||
Please note, that the fields here are identified by their JSON tags, not the struct field names. | ||
|
||
### Adding completely new fields | ||
|
||
For adding fields, that are not present in the model struct or you didn't want to include in the `WithModelFields` method, you can use the `WithField` method. More about fields can be found in the [Fields](#fields) section. | ||
|
||
```go | ||
serializer := serializers.NewModelSerializer[Model]().WithNewField( | ||
fields.NewField("color").ReadOnly().WithRepresentationFunc( | ||
func(models.InternalValue, string, *gin.Context) (any, error) { | ||
return "blue", nil | ||
} | ||
) | ||
) | ||
``` | ||
|
||
### Customizing existing fields | ||
|
||
You can also customize existing fields by using the `WithField` method. | ||
|
||
```go | ||
|
||
serializer := serializers.NewModelSerializer[Model]().WithField( | ||
"color", | ||
func(oldField fields.Field){ | ||
return oldField.WithRepresentationFunc( | ||
func(models.InternalValue, string, *gin.Context) (any, error) { | ||
return "pink", nil | ||
} | ||
) | ||
} | ||
) | ||
``` | ||
|
||
## Fields | ||
|
||
Fields are used by ModelSerializers to transform data between the database and the API on the single JSON field / SQL column level. They can be created with `fields.NewField("field_name")`. The API is pretty straightforward, please consult the [godoc](https://pkg.go.dev/github.com/glothriel/grf/pkg/fields). | ||
|
||
TLDR; you can: | ||
|
||
* Set the field as read-only, write-only or read-write | ||
* Set the InternalValue function, that will be used to transform the data from the API to format that can be stored in the database | ||
* Set the Representation function, that will be used to transform the data from the database to the API response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,63 @@ | ||
module github.com/glothriel/grf | ||
|
||
go 1.21 | ||
go 1.21.0 | ||
|
||
toolchain go1.23.6 | ||
|
||
require ( | ||
github.com/gin-gonic/gin v1.9.1 | ||
github.com/go-playground/assert/v2 v2.2.0 | ||
github.com/go-playground/validator/v10 v10.14.1 | ||
github.com/google/uuid v1.3.0 | ||
github.com/fergusstrange/embedded-postgres v1.30.0 | ||
github.com/gin-gonic/gin v1.10.0 | ||
github.com/go-playground/validator/v10 v10.25.0 | ||
github.com/google/uuid v1.6.0 | ||
github.com/mitchellh/mapstructure v1.5.0 | ||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 | ||
github.com/shopspring/decimal v1.3.1 | ||
github.com/sirupsen/logrus v1.9.3 | ||
github.com/stretchr/testify v1.8.4 | ||
github.com/stretchr/testify v1.10.0 | ||
gorm.io/driver/postgres v1.5.11 | ||
gorm.io/driver/sqlite v1.5.2 | ||
gorm.io/gorm v1.25.2 | ||
gorm.io/gorm v1.25.12 | ||
) | ||
|
||
require ( | ||
github.com/bytedance/sonic v1.9.2 // indirect | ||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect | ||
github.com/bytedance/sonic v1.12.8 // indirect | ||
github.com/bytedance/sonic/loader v0.2.3 // indirect | ||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect | ||
github.com/cloudwego/base64x v0.1.5 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect | ||
github.com/gin-contrib/sse v0.1.0 // indirect | ||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect | ||
github.com/gin-contrib/sse v1.0.0 // indirect | ||
github.com/go-playground/locales v0.14.1 // indirect | ||
github.com/go-playground/universal-translator v0.18.1 // indirect | ||
github.com/goccy/go-json v0.10.2 // indirect | ||
github.com/goccy/go-json v0.10.5 // indirect | ||
github.com/jackc/pgpassfile v1.0.0 // indirect | ||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect | ||
github.com/jackc/pgx/v5 v5.5.5 // indirect | ||
github.com/jackc/puddle/v2 v2.2.1 // indirect | ||
github.com/jinzhu/inflection v1.0.0 // indirect | ||
github.com/jinzhu/now v1.1.5 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect | ||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect | ||
github.com/kr/pretty v0.3.1 // indirect | ||
github.com/leodido/go-urn v1.2.4 // indirect | ||
github.com/mattn/go-isatty v0.0.19 // indirect | ||
github.com/mattn/go-sqlite3 v1.14.17 // indirect | ||
github.com/leodido/go-urn v1.4.0 // indirect | ||
github.com/lib/pq v1.10.9 // indirect | ||
github.com/mattn/go-isatty v0.0.20 // indirect | ||
github.com/mattn/go-sqlite3 v1.14.22 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect | ||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/rogpeppe/go-internal v1.11.0 // indirect | ||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||
github.com/ugorji/go/codec v1.2.11 // indirect | ||
golang.org/x/arch v0.3.0 // indirect | ||
golang.org/x/crypto v0.10.0 // indirect | ||
golang.org/x/net v0.11.0 // indirect | ||
golang.org/x/sys v0.9.0 // indirect | ||
golang.org/x/text v0.10.0 // indirect | ||
github.com/ugorji/go/codec v1.2.12 // indirect | ||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect | ||
golang.org/x/arch v0.14.0 // indirect | ||
golang.org/x/crypto v0.33.0 // indirect | ||
golang.org/x/net v0.35.0 // indirect | ||
golang.org/x/sync v0.11.0 // indirect | ||
golang.org/x/sys v0.30.0 // indirect | ||
golang.org/x/text v0.22.0 // indirect | ||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect | ||
google.golang.org/protobuf v1.31.0 // indirect | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||
google.golang.org/protobuf v1.36.5 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
Oops, something went wrong.