github.com/graphql-editor/azure-functions-golang-worker@v0.1.0/api/api.go (about) 1 // Package api available to user functions. User function must be a type 2 // that implements either Function or ReturnFunction interface. 3 // Function type for structs MUST be implemented on pointer reciever. 4 // User's function type MUST be exported using variable named Function (default) or otherwise defined EntryPoint in function.json (according to GoLang export rules, name MUST begin with capital letter). EntryPoint must be a valid GoLang identifier (https://golang.org/ref/spec#Identifiers). 5 // Inputs and outputs are read and written in similar fashion to a encoding/json package 6 // 7 // If a function object is a struct, the field name or a tag named `azfunc` must match trigger type for triggers and binding name for bindings. Field tag takes priority over field name. Field must be exported. If there's no tag, field name is compared using Unicode case-folding. 8 // If a function object is a map, keys in map match the type of a trigger for function triggers and a name of a binding for the rest of bindings. 9 // 10 // It is not an error if binding is missing from Function struct. 11 // 12 // For instance a struct object: 13 // package main 14 // type HTTPTrigger struct { 15 // // HttpTrigger represents function trigger. Function structure 16 // // can have at most one trigger defined. 17 // HttpTrigger *api.Request `azfunc:"httpTrigger"` 18 // // Additional input from, for instance, blob storage, named Original 19 // Original []byte `azfunc:"original"` 20 // // Response object using named output binding `res` 21 // Response api.Response `azfunc:"res"` 22 // } 23 // func (f *HTTPTrigger) Run(ctx context.Context, logger api.Logger) { 24 // f.Response.Body = "data" 25 // } 26 // var Function *HTTPTrigger 27 // 28 // For triggers that support $return value binding they can be implemented as so 29 // package main 30 // type HTTPTrigger struct { 31 // // HttpTrigger represents function trigger. Function structure 32 // // can have at most one trigger defined. 33 // HttpTrigger *api.Request `azfunc:"httpTrigger"` 34 // } 35 // func (f *HTTPTrigger) Run(ctx context.Context, logger api.Logger) interface{} { 36 // return api.Response{ 37 // Body: "data", 38 // } 39 // } 40 // var Function *HTTPTrigger 41 // 42 // Worker also supports simple map type definitions as function objects 43 // package main 44 // type HTTPTrigger map[string]interface{} 45 // func (f Function) Run(ctx context.Context, logger api.Logger) { 46 // f.["res"] = api.Response{ 47 // Body: "data", 48 // } 49 // } 50 // var Function HTTPTrigger 51 // 52 // If scriptFile in function.json is empty, whole function package is built, similar to `go build .`, otherwise only file indicated by scriptFile is built and other go sources in function directory are ignored. 53 package api 54 55 import ( 56 "context" 57 "net/http" 58 "net/url" 59 "time" 60 61 "github.com/graphql-editor/azure-functions-golang-worker/converters" 62 "github.com/graphql-editor/azure-functions-golang-worker/rpc" 63 "github.com/pkg/errors" 64 ) 65 66 // Logger interface 67 type Logger interface { 68 Trace(string) 69 Tracef(string, ...interface{}) 70 Debug(string) 71 Debugf(string, ...interface{}) 72 Info(string) 73 Infof(string, ...interface{}) 74 Warn(string) 75 Warnf(string, ...interface{}) 76 Error(string) 77 Errorf(string, ...interface{}) 78 Fatal(string) 79 Fatalf(string, ...interface{}) 80 } 81 82 // Function interface that must be implemented by user's function object. Function 83 // does not return a value. 84 type Function interface { 85 Run(context.Context, Logger) 86 } 87 88 // ReturnFunction interface that must be implemented by user's function object. Function 89 // returns a value. 90 type ReturnFunction interface { 91 Run(context.Context, Logger) interface{} 92 } 93 94 // Request represents httpTrigger in function definition. 95 type Request struct { 96 Method string 97 URL string 98 Headers http.Header 99 Query url.Values 100 Params url.Values 101 Body interface{} 102 RawBody interface{} 103 } 104 105 // Unmarshal implements unmarshaler for api.Request 106 func (r *Request) Unmarshal(data *rpc.TypedData) error { 107 req, ok := data.Data.(*rpc.TypedData_Http) 108 if !ok { 109 return errors.Errorf("not a http request trigger") 110 } 111 body, rawBody, err := converters.DecodeHTTPBody(req.Http) 112 if err == nil { 113 *r = Request{ 114 Method: req.Http.GetMethod(), 115 URL: req.Http.GetUrl(), 116 Headers: converters.DecodeHeaders(req.Http.GetHeaders()), 117 Query: converters.DecodeValues(req.Http.GetQuery()), 118 Params: converters.DecodeValues(req.Http.GetParams()), 119 Body: body, 120 RawBody: rawBody, 121 } 122 } 123 return nil 124 } 125 126 // CookiePolicy for cross-site requests 127 type CookiePolicy string 128 129 const ( 130 // Strict policy 131 Strict CookiePolicy = "Strict" 132 // Lax policy 133 Lax CookiePolicy = "Lax" 134 ) 135 136 // Cookie used with http response Set-Cookie 137 type Cookie struct { 138 Name string 139 Value string 140 Domain *string 141 Path *string 142 Expires *time.Time 143 Secure *bool 144 HTTPOnly *bool 145 SameSite CookiePolicy 146 MaxAge *float64 147 } 148 149 // Cookies list 150 type Cookies []Cookie 151 152 // Response represents response from function when using HTTP output binding 153 type Response struct { 154 Headers http.Header 155 Cookies Cookies 156 StatusCode int 157 Body interface{} 158 } 159 160 // Marshal implements Marshaler for converters 161 func (r Response) Marshal() (*rpc.TypedData, error) { 162 return encodeResponseObject(&r) 163 } 164 165 type contextKey string 166 167 // TriggerMetadataKey is a context key for trigger data 168 var TriggerMetadataKey contextKey = contextKey("triggerMetadataKey") 169 170 // GetTriggerMetadata returns trigger metadata associated with trigger 171 func GetTriggerMetadata(ctx context.Context) map[string]interface{} { 172 v, ok := ctx.Value(TriggerMetadataKey).(map[string]interface{}) 173 if !ok { 174 return nil 175 } 176 return v 177 }