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  }