Annotations support for Go
This project provides ability to add Java-style annotations in the comments to struct, interface, method and/or func. Annotations from comments are transformed into objects and mapped to provided struct for use in the code. Code generation (go generate) is used to create the registry of all annotations in the project.
-
Make sure you're using Go 1.6+
-
Install or update it:
go get -u github.com/SphereSoftware/go-annotations
-
Define you first annotation in any go source file, for example
annotation.go
:type Entity struct { Name string `default:"unknown"` }
-
Define your annotated entity in any other (or the same) go source file
example.go
:package example //go:generate go-annotations type ( // @Entity(name="test") Person struct { Id int FullName string } )
-
Use that annotation in the code somewhere else:
import ( "github.com/SphereSoftware/go-annotations/registry" ) func Test() { a := registry.GetStructAnnotatoin(Person{}).(Entity) ... }
-
Run
go generate [package or file]
. This will createexample_annotations.go
in the same package with typePerson
- Annotation class inside the comments is started with the '@' character
- Top-level annotation's package should be included with _ alias
- Structures, interfaces, methods and functions can be annotated
- Annotation can contain parameters: comma-separated list of property-value pairs
- If annotation has only one attribute then only its value can be specified as the parameter
- Array property value is enclosed by {} and elements are comma-separated
- Property value can be string, number or another annotation
- For each annotation the corresponding struct should be defined
- Optional annotation attributes are defined as pointers types
- Defauld attribute value could be specified using field tag "default:"
- Annotation registry file is generated for the whole package
- At least one source with annotations should contain
go:generate
tag - The optional parameter of
go:generate
tag can specify the name of generated source file for regstry - Default registry source is named
<package_name>
+"_annotations.go" - The set of methods is provided to get annotations list for specified struct, func, interface or field name
The following functions from registry
package are provided to work with annotations:
func Map(s string, a Annotations)
- associates the set of annotations with given tag. Tag contains the information about full package name and object name in form of<full_package_name>
.<object_name>
func MapType(i interface{}, a Annotations)
- maps annotation bundle to the type and name of provided objectfunc GetStructAnnotations(s interface{}) []interface{}
- returns struct/interface/func level annotations. Parameter can be either object instance or object'srefect.Type
instance or string with object's package and name information, as described forMap
functionfunc GetFieldAnnotations(s interface{}, fieldName string) []interface{}
- returns annotations bundle for specified field of provided object typefunc GetMethodAnnotations(s interface{}, methodName string) []interface{}
- returns annotations bundle for specified method of provided object typefunc GetFuncAnnotation(s interface{}) []interface{}
- returns annotations bundle for provided func type
package example
import (
"github.com/SphereSoftware/go-annotations/example/test"
"github.com/SphereSoftware/go-annotations/registry"
)
//go:generate go-annotations my_annotations
type (
// @Entity(Name="test", Books={@Book(Name="book",Author=@Person("Mr.X"))})
Test struct{}
//@Entity
Test2 struct {
//@Book
Name string
}
// @Entity
Sample interface {
// @Book
doSomething(s string) int
}
)
// @Entity
func (*Test) methodOfTest() {
...
}
// @Book
func JustAFunc() {
...
}
package test
import (
r "github.com/SphereSoftware/go-annotations/example/test2"
)
type (
Entity struct {
Name string
Books []Book
}
Book struct {
Name string
Price float32 `default:"1.0"`
Author *r.Person
}
)
package test2
type (
Person struct {
Name string
}
)