Skip to content
Merged
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
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ Built on top of Gin.
Restman can be used with any database as long as you implement the builtin repository interface
It come with its own GORM based implementation, compatible with Entity/Model separation but also a more straighforward approach.

## Features
## Features
Fully working structure to REST automated route generation using GIN, recursion and generics
Out of the box GORM based ORM
Firewall implementation allowing to filter who can access/edit which data
Serialization groups to control which property are allowed to be readed or wrote using the generated route
Out of the box GORM based ORM
Firewall implementation allowing to filter who can access/edit which data
Serialization groups to control which property are allowed to be readed or wrote using the generated route
Multiple output formats: JSON, JSON-LD, XML, CSV, MessagePack


## TODO, Ideas for myself and for random contributors
Expand All @@ -21,10 +22,9 @@ entity.ID UUID compatiblility
InMemory cache with default redis integration
Mongo default Repository
Fix XML serialialization
fix CSV serialialization
fix CSV serialialization
Check current golang json serialization speed
check force lowercase for json ? (golang default serializer is like the only thing in the world who does nt force lowercase)
check messagepack
Serializer could be refactord
Somehow hooks could be nice ?? (meh)
The fireWall could have a builtin requireOwnership
Expand Down
13 changes: 7 additions & 6 deletions format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ type Format string

// Const of default formats handled by RestMan
const (
Undefined Format = "undefined"
Unknown = "unknown"
JSON = "application/json"
JSONLD = "application/ld+json"
XML = "text/xml"
CSV = "application/csv"
Undefined Format = "undefined"
Unknown = "unknown"
JSON = "application/json"
JSONLD = "application/ld+json"
XML = "text/xml"
CSV = "application/csv"
MESSAGEPACK = "application/msgpack"
)
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ require (
github.com/onsi/gomega v1.38.2 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
Expand Down
11 changes: 7 additions & 4 deletions router/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ type SerializerRenderer struct {
}

var (
jsonContentType = []string{"application/json; charset=utf-8"}
jsonldContentType = []string{"application/ld-json; charset=utf-8"}
xmlContentType = []string{"application/xml; charset=utf-8"}
csvContentType = []string{"text/csv"}
jsonContentType = []string{"application/json; charset=utf-8"}
jsonldContentType = []string{"application/ld-json; charset=utf-8"}
xmlContentType = []string{"application/xml; charset=utf-8"}
csvContentType = []string{"text/csv"}
messagepackContentType = []string{"application/msgpack"}
)

// Render
Expand All @@ -43,6 +44,8 @@ func (r SerializerRenderer) WriteContentType(w http.ResponseWriter) {
writeContentType(w, xmlContentType)
case format.CSV:
writeContentType(w, csvContentType)
case format.MESSAGEPACK:
writeContentType(w, messagepackContentType)
}
}

Expand Down
7 changes: 7 additions & 0 deletions serializer/deserialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/philiphil/restman/format"
"github.com/philiphil/restman/serializer/filter"
"github.com/vmihailenco/msgpack/v5"
)

// Deserializer encapsulates the deserialization logic
Expand All @@ -26,6 +27,8 @@ func (s *Serializer) Deserialize(data string, obj any) error {
return s.deserializeXML(data, obj)
case format.CSV:
return s.deserializeCSV(data, obj)
case format.MESSAGEPACK:
return s.deserializeMessagePack(data, obj)
default:
return fmt.Errorf("unsupported format: %s", s.Format)
}
Expand Down Expand Up @@ -325,3 +328,7 @@ func setFieldFromString(field reflect.Value, value string) error {
}
return nil
}

func (s *Serializer) deserializeMessagePack(data string, obj any) error {
return msgpack.Unmarshal([]byte(data), obj)
}
15 changes: 15 additions & 0 deletions serializer/serialize.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package serializer

import (
"bytes"
"encoding/csv"
"encoding/json"
"encoding/xml"
Expand All @@ -10,6 +11,7 @@ import (

"github.com/philiphil/restman/format"
"github.com/philiphil/restman/serializer/filter"
"github.com/vmihailenco/msgpack/v5"
)

type xmlFilterWrapper struct {
Expand Down Expand Up @@ -107,6 +109,8 @@ func (s *Serializer) Serialize(obj any, groups ...string) (string, error) {
return s.serializeXML(obj, groups...)
case format.CSV:
return s.serializeCSV(obj, groups...)
case format.MESSAGEPACK:
return s.serializeMessagePack(obj, groups...)
default:
return "", fmt.Errorf("unsupported format: %s", s.Format)
}
Expand Down Expand Up @@ -229,3 +233,14 @@ func writeCSVToString(rows [][]string) (string, error) {
}
return sb.String(), nil
}

func (s *Serializer) serializeMessagePack(obj any, groups ...string) (string, error) {
data := filter.FilterByGroups(obj, groups...)
var buf bytes.Buffer
encoder := msgpack.NewEncoder(&buf)
encoder.SetCustomStructTag("json")
if err := encoder.Encode(data); err != nil {
return "", err
}
return buf.String(), nil
}
Loading