Skip to content

Commit

Permalink
feat: switch alias to json (#943)
Browse files Browse the repository at this point in the history
Fixes #908

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
wesbillman and github-actions[bot] authored Feb 15, 2024
1 parent 183afa5 commit ee0010d
Show file tree
Hide file tree
Showing 20 changed files with 304 additions and 304 deletions.
12 changes: 6 additions & 6 deletions backend/controller/ingress/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,20 @@ func transformAliasedFields(sch *schema.Schema, t schema.Type, obj any, aliaser

func transformFromAliasedFields(dataRef *schema.DataRef, sch *schema.Schema, request map[string]any) (map[string]any, error) {
return request, transformAliasedFields(sch, dataRef, request, func(obj map[string]any, field *schema.Field) string {
if _, ok := obj[field.Name]; !ok && field.Alias != "" && obj[field.Alias] != nil {
obj[field.Name] = obj[field.Alias]
delete(obj, field.Alias)
if _, ok := obj[field.Name]; !ok && field.JSONAlias != "" && obj[field.JSONAlias] != nil {
obj[field.Name] = obj[field.JSONAlias]
delete(obj, field.JSONAlias)
}
return field.Name
})
}

func transformToAliasedFields(dataRef *schema.DataRef, sch *schema.Schema, request map[string]any) (map[string]any, error) {
return request, transformAliasedFields(sch, dataRef, request, func(obj map[string]any, field *schema.Field) string {
if field.Alias != "" && field.Name != field.Alias {
obj[field.Alias] = obj[field.Name]
if field.JSONAlias != "" && field.Name != field.JSONAlias {
obj[field.JSONAlias] = obj[field.Name]
delete(obj, field.Name)
return field.Alias
return field.JSONAlias
}
return field.Name
})
Expand Down
8 changes: 4 additions & 4 deletions backend/controller/ingress/alias_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ func TestTransformFromAliasedFields(t *testing.T) {
schemaText := `
module test {
data Inner {
waz String alias foo
waz String alias json foo
}
data Test {
scalar String alias bar
scalar String alias json bar
inner Inner
array [Inner]
map {String: Inner}
Expand Down Expand Up @@ -72,11 +72,11 @@ func TestTransformToAliasedFields(t *testing.T) {
schemaText := `
module test {
data Inner {
waz String alias foo
waz String alias json foo
}
data Test {
scalar String alias bar
scalar String alias json bar
inner Inner
array [Inner]
map {String: Inner}
Expand Down
2 changes: 1 addition & 1 deletion backend/controller/ingress/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func TestResponseBodyForVerb(t *testing.T) {
&schema.Data{
Name: "Test",
Fields: []*schema.Field{
{Name: "message", Type: &schema.String{}, Alias: "msg"},
{Name: "message", Type: &schema.String{}, JSONAlias: "msg"},
},
},
jsonVerb,
Expand Down
2 changes: 1 addition & 1 deletion backend/controller/ingress/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func parseQueryParams(values url.Values, data *schema.Data) (map[string]any, err

var field *schema.Field
for _, f := range data.Fields {
if (f.Alias != "" && f.Alias == key) || f.Name == key {
if (f.JSONAlias != "" && f.JSONAlias == key) || f.Name == key {
field = f
}
for _, typeParam := range data.TypeParameters {
Expand Down
6 changes: 3 additions & 3 deletions backend/controller/ingress/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ func bodyForType(typ schema.Type, sch *schema.Schema, data []byte) ([]byte, erro
}

err = transformAliasedFields(sch, t, response, func(obj map[string]any, field *schema.Field) string {
if field.Alias != "" && field.Name != field.Alias {
obj[field.Alias] = obj[field.Name]
if field.JSONAlias != "" && field.Name != field.JSONAlias {
obj[field.JSONAlias] = obj[field.Name]
delete(obj, field.Name)
return field.Alias
return field.JSONAlias
}
return field.Name
})
Expand Down
28 changes: 14 additions & 14 deletions backend/schema/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import (
type Field struct {
Pos Position `parser:"" protobuf:"1,optional"`

Comments []string `parser:"@Comment*" protobuf:"3"`
Name string `parser:"@Ident" protobuf:"2"`
Type Type `parser:"@@" protobuf:"4"`
Alias string `parser:"('alias' @Ident)?" protobuf:"5"`
Comments []string `parser:"@Comment*" protobuf:"3"`
Name string `parser:"@Ident" protobuf:"2"`
Type Type `parser:"@@" protobuf:"4"`
JSONAlias string `parser:"('alias' 'json' @Ident)?" protobuf:"5"`
}

var _ Node = (*Field)(nil)

func (f *Field) Position() Position { return f.Pos }
func (f *Field) schemaChildren() []Node { return []Node{f.Type} }
func (f *Field) String() string {
alias := ""
if f.Alias != "" {
alias = fmt.Sprintf(" alias %s", f.Alias)
jsonAlias := ""
if f.JSONAlias != "" {
jsonAlias = fmt.Sprintf(" alias json %s", f.JSONAlias)
}
w := &strings.Builder{}
fmt.Fprint(w, encodeComments(f.Comments))
fmt.Fprintf(w, "%s %s%s", f.Name, f.Type.String(), alias)
fmt.Fprintf(w, "%s %s%s", f.Name, f.Type.String(), jsonAlias)
return w.String()
}

Expand All @@ -39,7 +39,7 @@ func (f *Field) ToProto() proto.Message {
Name: f.Name,
Type: typeToProto(f.Type),
Comments: f.Comments,
Alias: f.Alias,
Alias: f.JSONAlias,
}
}

Expand All @@ -53,10 +53,10 @@ func fieldListToSchema(s []*schemapb.Field) []*Field {

func fieldToSchema(s *schemapb.Field) *Field {
return &Field{
Pos: posFromProto(s.Pos),
Name: s.Name,
Comments: s.Comments,
Type: typeToSchema(s.Type),
Alias: s.Alias,
Pos: posFromProto(s.Pos),
Name: s.Name,
Comments: s.Comments,
Type: typeToSchema(s.Type),
JSONAlias: s.Alias,
}
}
12 changes: 6 additions & 6 deletions backend/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ func TestSchemaString(t *testing.T) {
// A comment
module todo {
data CreateRequest {
name {String: String}? alias rqn
name {String: String}? alias json rqn
}
data CreateResponse {
name [String] alias rsn
name [String] alias json rsn
}
data DestroyRequest {
Expand Down Expand Up @@ -340,10 +340,10 @@ func TestParseModule(t *testing.T) {
// A comment
module todo {
data CreateRequest {
name {String: String}? alias rqn
name {String: String}? alias json rqn
}
data CreateResponse {
name [String] alias rsn
name [String] alias json rsn
}
data DestroyRequest {
// A comment
Expand Down Expand Up @@ -374,13 +374,13 @@ var testSchema = MustValidate(&Schema{
&Data{
Name: "CreateRequest",
Fields: []*Field{
{Name: "name", Type: &Optional{Type: &Map{Key: &String{}, Value: &String{}}}, Alias: "rqn"},
{Name: "name", Type: &Optional{Type: &Map{Key: &String{}, Value: &String{}}}, JSONAlias: "rqn"},
},
},
&Data{
Name: "CreateResponse",
Fields: []*Field{
{Name: "name", Type: &Array{Element: &String{}}, Alias: "rsn"},
{Name: "name", Type: &Array{Element: &String{}}, JSONAlias: "rsn"},
},
},
&Data{
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions go-runtime/compile/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
})
ftlCallFuncPath = "github.com/TBD54566975/ftl/go-runtime/ftl.Call"

aliasFieldTag = "alias"
aliasFieldTag = "json"
)

// NativeNames is a map of top-level declarations to their native Go names.
Expand Down Expand Up @@ -418,10 +418,10 @@ func visitStruct(pctx *parseContext, node ast.Node, tnode types.Type) (*schema.D
}

out.Fields = append(out.Fields, &schema.Field{
Pos: goPosToSchemaPos(node.Pos()),
Name: strcase.ToLowerCamel(f.Name()),
Type: ft,
Alias: reflect.StructTag(s.Tag(i)).Get(aliasFieldTag),
Pos: goPosToSchemaPos(node.Pos()),
Name: strcase.ToLowerCamel(f.Name()),
Type: ft,
JSONAlias: reflect.StructTag(s.Tag(i)).Get(aliasFieldTag),
})
}
pctx.module.AddData(out)
Expand Down
2 changes: 1 addition & 1 deletion go-runtime/compile/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestExtractModuleSchema(t *testing.T) {
nested one.Nested
optional one.Nested?
time Time
user two.User alias u
user two.User alias json u
bytes Bytes
}
Expand Down
2 changes: 1 addition & 1 deletion go-runtime/compile/testdata/one/one.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Req struct {
Nested Nested
Optional ftl.Option[Nested]
Time time.Time
User two.User `alias:"u"`
User two.User `json:"u"`
Bytes []byte
}
type Resp struct{}
Expand Down
22 changes: 11 additions & 11 deletions integration/testdata/go/httpingress/echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ import (
)

type GetRequest struct {
UserID string `alias:"userId"`
PostID string `alias:"postId"`
UserID string `json:"userId"`
PostID string `json:"postId"`
}

type Nested struct {
GoodStuff string `alias:"good_stuff"`
GoodStuff string `json:"good_stuff"`
}

type GetResponse struct {
Message string `alias:"msg"`
Nested Nested `alias:"nested"`
Message string `json:"msg"`
Nested Nested `json:"nested"`
}

//ftl:verb
Expand All @@ -39,12 +39,12 @@ func Get(ctx context.Context, req builtin.HttpRequest[GetRequest]) (builtin.Http
}

type PostRequest struct {
UserID int `alias:"user_id"`
UserID int `json:"user_id"`
PostID int
}

type PostResponse struct {
Success bool `alias:"success"`
Success bool `json:"success"`
}

//ftl:verb
Expand All @@ -58,8 +58,8 @@ func Post(ctx context.Context, req builtin.HttpRequest[PostRequest]) (builtin.Ht
}

type PutRequest struct {
UserID string `alias:"userId"`
PostID string `alias:"postId"`
UserID string `json:"userId"`
PostID string `json:"postId"`
}

type PutResponse struct{}
Expand All @@ -74,7 +74,7 @@ func Put(ctx context.Context, req builtin.HttpRequest[PutRequest]) (builtin.Http
}

type DeleteRequest struct {
UserID string `alias:"userId"`
UserID string `json:"userId"`
}

type DeleteResponse struct{}
Expand Down Expand Up @@ -154,7 +154,7 @@ func ArrayString(ctx context.Context, req builtin.HttpRequest[[]string]) (builti
}

type ArrayType struct {
Item string `alias:"item"`
Item string `json:"item"`
}

//ftl:verb
Expand Down
24 changes: 12 additions & 12 deletions integration/testdata/kotlin/httpingress/Echo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,46 @@ import ftl.builtin.HttpRequest
import ftl.builtin.HttpResponse
import kotlin.String
import kotlin.Unit
import xyz.block.ftl.Alias
import xyz.block.ftl.Json
import xyz.block.ftl.Context
import xyz.block.ftl.HttpIngress
import xyz.block.ftl.Method
import xyz.block.ftl.Verb

data class GetRequest(
@Alias("userId") val userID: String,
@Alias("postId") val postID: String,
@Json("userId") val userID: String,
@Json("postId") val postID: String,
)

data class Nested(
@Alias("good_stuff") val goodStuff: String,
@Json("good_stuff") val goodStuff: String,
)

data class GetResponse(
@Alias("msg") val message: String,
@Alias("nested") val nested: Nested,
@Json("msg") val message: String,
@Json("nested") val nested: Nested,
)

data class PostRequest(
@Alias("user_id") val userId: Int,
@Json("user_id") val userId: Int,
val postId: Int,
)

data class PostResponse(
@Alias("success") val success: Boolean,
@Json("success") val success: Boolean,
)

data class PutRequest(
@Alias("userId") val userID: String,
@Alias("postId") val postID: String,
@Json("userId") val userID: String,
@Json("postId") val postID: String,
)

data class DeleteRequest(
@Alias("userId") val userID: String,
@Json("userId") val userID: String,
)

data class ArrayType(
@Alias("item") val item: String,
@Json("item") val item: String,
)

@Verb
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class ModuleGenerator {
dataConstructorBuilder.addParameter(parameter.build())
dataClassBuilder.addProperty(
PropertySpec.builder(field.name, getTypeClass(type, namespace)).initializer(field.name).let {
if (field.alias != "") {
if (field.jsonAlias != "") {
it.addAnnotation(
AnnotationSpec.builder(xyz.block.ftl.Alias::class).addMember("%S", field.alias).build()
AnnotationSpec.builder(xyz.block.ftl.Json::class).addMember("%S", field.jsonAlias).build()
)
} else {
it
Expand Down
Loading

0 comments on commit ee0010d

Please sign in to comment.