JSON API ResourceObject GOA
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
// Definition | |
/* | |
func test() { | |
account := app.AccountSingle{} | |
account.Data.ID | |
account.Data.Type | |
account.Data.Attributes.Name | |
account.Data.Relationships.OwnedBy | |
account.Data.Relationships.OwnedBy.Meta | |
account.Data.Relationships.OwnedBy.Related | |
account.Data.Relationships.OwnedBy.Self | |
account.Links.Self | |
account.Meta | |
account.Included | |
} | |
*/ | |
var account = ResourceObject( | |
"Account", | |
"Account is the representation of the owning entity of a Space. Account could be owned by either a User or a Org.", | |
ResourceObjectData("AccountData", func() { | |
a.Attribute("name", d.String) | |
}, "owned-by"), | |
"self") | |
var _ = ResourceObject( | |
"Organization", | |
"Organization is the representation of the owning entity of a Space", | |
ResourceObjectData("Organization", func() { | |
a.Attribute("name", d.String) | |
}, "belongs-to", "paied-by"), | |
"self") | |
var _ = ResourceObjectEntrypoint(account, "create", "show", "update", "delete", "list") | |
// helpers | |
func ResourceObjectData(name string, attrs func(), relations ...string) *d.UserTypeDefinition { | |
return a.Type(name, func() { | |
a.Attribute("type", d.String) | |
a.Attribute("id", d.String, "UUID of the object", func() { | |
a.Example("6c5610be-30b2-4880-9fec-81e4f8e4fd76") | |
}) | |
a.Attribute("attributes", attrs) | |
if relations != nil { | |
a.Attribute("relationships", func() { | |
for _, link := range relations { | |
a.Attribute(link, resourceLink) | |
} | |
}) | |
} | |
}) | |
} | |
func ResourceObject(name, description string, data *d.UserTypeDefinition, links ...string) *d.MediaTypeDefinition { | |
return a.MediaType("application/vnd."+strings.ToLower(name)+"+json", func() { | |
a.UseTrait("jsonapi-media-type") | |
a.TypeName(name + "Single") | |
a.Description(description) | |
if links != nil { | |
a.Attribute("links", func() { | |
for _, link := range links { | |
a.Attribute(link, resourceLink) | |
} | |
}) | |
} | |
a.Attribute("data", data) | |
a.Attribute("meta", a.HashOf(d.String, d.Any)) | |
a.Attribute("included", a.ArrayOf(d.Any), "An array of mixed types") | |
a.Required("data") | |
a.View("default", func() { | |
if links != nil { | |
a.Attribute("links") | |
} | |
a.Attribute("data") | |
a.Attribute("included") | |
a.Attribute("meta") | |
a.Required("data") | |
}) | |
}) | |
} | |
func ResourceObjectEntrypoint(media *d.MediaTypeDefinition, actions ...string) *d.ResourceDefinition { | |
name := strings.Replace(strings.ToLower(media.TypeName), "single", "", -1) | |
return a.Resource(name, func() { | |
fmt.Println(name) | |
a.BasePath("/" + name) | |
for _, action := range actions { | |
switch action { | |
case "show": | |
a.Action("show", func() { | |
a.Routing( | |
a.GET("/:" + name + "ID"), | |
) | |
a.Description("Retrieve " + name + " (as JSONAPI) for the given ID.") | |
a.Params(func() { | |
a.Param(name+"ID", d.UUID, "ID of the "+name) | |
}) | |
a.UseTrait("conditional") | |
a.Response(d.OK, media) | |
a.Response(d.NotModified) | |
a.Response(d.BadRequest, JSONAPIErrors) | |
a.Response(d.InternalServerError, JSONAPIErrors) | |
a.Response(d.NotFound, JSONAPIErrors) | |
}) | |
case "list": | |
a.Action("list", func() { | |
a.Security("jwt") | |
a.Routing( | |
a.GET(""), | |
) | |
a.Description("List " + name + "s.") | |
a.Params(func() { | |
a.Param("page[offset]", d.String, "Paging start position") | |
a.Param("page[limit]", d.Integer, "Paging size") | |
}) | |
a.UseTrait("conditional") | |
a.Response(d.OK, media) | |
a.Response(d.NotModified) | |
a.Response(d.BadRequest, JSONAPIErrors) | |
a.Response(d.InternalServerError, JSONAPIErrors) | |
a.Response(d.Unauthorized, JSONAPIErrors) | |
}) | |
case "create": | |
a.Action("create", func() { | |
a.Security("jwt") | |
a.Routing( | |
a.POST(""), | |
) | |
a.Description("Create a " + name) | |
a.Payload(media) | |
a.Response(d.Created, "/"+name+"s/.*", func() { | |
a.Media(media) | |
}) | |
a.Response(d.BadRequest, JSONAPIErrors) | |
a.Response(d.InternalServerError, JSONAPIErrors) | |
a.Response(d.Unauthorized, JSONAPIErrors) | |
a.Response(d.Conflict, JSONAPIErrors) | |
}) | |
case "update": | |
a.Action("delete", func() { | |
a.Security("jwt") | |
a.Routing( | |
a.DELETE("/:" + name + "ID"), | |
) | |
a.Description("Delete a " + name + " with the given ID.") | |
a.Params(func() { | |
a.Param(name+"ID", d.UUID, "ID of the "+name+" to delete") | |
}) | |
a.Response(d.OK) | |
a.Response(d.BadRequest, JSONAPIErrors) | |
a.Response(d.InternalServerError, JSONAPIErrors) | |
a.Response(d.NotFound, JSONAPIErrors) | |
a.Response(d.Unauthorized, JSONAPIErrors) | |
a.Response(d.Forbidden, JSONAPIErrors) | |
}) | |
case "delete": | |
a.Action("update", func() { | |
a.Security("jwt") | |
a.Routing( | |
a.PATCH("/:" + name + "ID"), | |
) | |
a.Description("Update the " + name + " with the given ID.") | |
a.Params(func() { | |
a.Param(name+"ID", d.UUID, "ID of the "+name+" to update") | |
}) | |
a.Payload(media) | |
a.Response(d.OK, func() { | |
a.Media(media) | |
}) | |
a.Response(d.BadRequest, JSONAPIErrors) | |
a.Response(d.Conflict, JSONAPIErrors) | |
a.Response(d.InternalServerError, JSONAPIErrors) | |
a.Response(d.NotFound, JSONAPIErrors) | |
a.Response(d.Unauthorized, JSONAPIErrors) | |
a.Response(d.Forbidden, JSONAPIErrors) | |
}) | |
} | |
} | |
}) | |
} | |
var resourceLink = a.Type("ResourceLink", func() { | |
a.Attribute("self", d.String) | |
a.Attribute("related", d.String) | |
a.Attribute("meta", a.HashOf(d.String, d.Any)) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment