github.com/mjibson/goon@v1.1.0/doc.go (about) 1 /* 2 Package goon provides an autocaching interface to the app engine datastore 3 similar to the python NDB package. 4 5 Goon differs from the datastore package in various ways: it remembers the 6 appengine Context, which need only be specified once at creation time; kinds 7 need not be specified as they are computed, by default, from a type's name; 8 keys are inferred from specially-tagged fields on types, removing the need to 9 pass key objects around. 10 11 In general, the difference is that Goon's API is identical to the datastore API, 12 it's just shorter. 13 14 Keys in Goon are stored in the structs themselves. Below is an example struct 15 with a field to specify the id (see the Key Specifications section below for 16 full documentation). 17 type User struct { 18 Id string `datastore:"-" goon:"id"` 19 Name string 20 } 21 22 Thus, to get a User with id 2: 23 userid := 2 24 g := goon.NewGoon(r) 25 u := &User{Id: userid} 26 g.Get(u) 27 28 Key Specifications 29 30 For both the Key and KeyError functions, src must be a S or *S for some 31 struct type S. The key is extracted based on various fields of S. If a field 32 of type int64 or string has a struct tag named goon with value "id", it is 33 used as the key's id. If a field of type *datastore.Key has a struct tag 34 named goon with value "parent", it is used as the key's parent. If a field 35 of type string has a struct tag named goon with value "kind", it is used 36 as the key's kind. The "kind" field supports an optional second parameter 37 which is the default kind name. If no kind field exists, the struct's name 38 is used. These fields should all have their datastore field marked as "-". 39 40 Example, with kind User: 41 type User struct { 42 Id string `datastore:"-" goon:"id"` 43 Read time.Time 44 } 45 46 Example, with kind U if _kind is the empty string: 47 type User struct { 48 _kind string `goon:"kind,U"` 49 Id string `datastore:"-" goon:"id"` 50 Read time.Time 51 } 52 53 To override kind of a single entity to UserKind: 54 u := User{_kind: "UserKind"} 55 56 An example with both parent and kind: 57 type UserData struct { 58 Id string `datastore:"-" goon:"id"` 59 _kind string `goon:"kind,UD"` 60 Parent *datastore.Key `datastore:"-" goon:"parent"` 61 Data []byte 62 } 63 64 Features 65 66 Datastore interaction with: Get, GetMulti, Put, PutMulti, Delete, DeleteMulti, Queries. 67 68 All key-based operations backed by memory and memcache. 69 70 Per-request, in-memory cache: fetch the same key twice, the second request is served from local memory. 71 72 Intelligent multi support: running GetMulti correctly fetches from memory, then memcache, then the datastore; each tier only sends keys off to the next one if they were missing. 73 74 Memcache control variance: long memcache requests are cancelled. 75 76 Transactions use a separate context, but locally cache any results on success. 77 78 Automatic kind naming: struct names are inferred by reflection, removing the need to manually specify key kinds. 79 80 Simpler API than appengine/datastore. 81 82 API comparison between goon and datastore 83 84 put with incomplete key 85 86 datastore: 87 88 type Group struct { 89 Name string 90 } 91 c := appengine.NewContext(r) 92 g := &Group{Name: "name"} 93 k := datastore.NewIncompleteKey(c, "Group", nil) 94 err := datastore.Put(c, k, g) 95 96 goon: 97 98 type Group struct { 99 Id int64 `datastore:"-" goon:"id"` 100 Name string 101 } 102 n := goon.NewGoon(r) 103 g := &Group{Name: "name"} 104 err := n.Put(g) 105 106 get with known key 107 108 datastore: 109 110 type Group struct { 111 Name string 112 } 113 c := appengine.NewContext(r) 114 g := &Group{} 115 k := datastore.NewKey(c, "Group", "", 1, nil) 116 err := datastore.Get(c, k, g) 117 118 goon: 119 120 type Group struct { 121 Id int64 `datastore:"-" goon:"id"` 122 Name string 123 } 124 n := goon.NewGoon(r) 125 g := &Group{Id: 1} 126 err := n.Get(g) 127 128 Memcache Control Variance 129 130 Memcache is generally fast. When it is slow, goon will timeout the memcache 131 requests and proceed to use the datastore directly. The memcache put and 132 get timeout variables determine how long to wait for various kinds of 133 requests. The default settings were determined experimentally and should 134 provide reasonable defaults for most applications. 135 136 See: http://talks.golang.org/2013/highperf.slide#23 137 138 PropertyLoadSaver support 139 140 Structs that implement the PropertyLoadSaver interface are guaranteed to call 141 the Save() method once and only once per Put/PutMulti call and never elsewhere. 142 Similarly the Load() method is guaranteed to be called once and only once per 143 Get/GetMulti/GetAll/Next call and never elsewhere. 144 145 */ 146 package goon