google app engine - Cross platform go code for appengine -
what go appropriate way create fetchurl/geturl function works command line , works google app engine custom way fetch url.
i have basic code fetches , processes data on url. want able call code use on desktop, , code deployed app engine.
hopefully thats clear, if not please let me know , ill clarify.
if have code works both on local machine , on appengine environment, have nothing do.
if need should or must done differently on appengine, need detect environment , write different code different environments.
this detection , code selection easiest done using build constraints. can put special comment line in beginning of .go file, , may or may not compiled , run depending on environment.
quoting the go blog: app engine sdk , workspaces (gopath):
the app engine sdk introduces new build constraint term:
"appengine". files specify// +build appenginewill built app engine sdk , ignored go tool. conversely, files specify
// +build !appengineare ignored app engine sdk, while go tool happily build them.
so example can have 2 separate .go files, 1 appengine , 1 local (non-appengine) environment. define same function in both (with same parameter list), no matter in environment code built, function have 1 declaration. use signature:
func geturl(url string, r *http.request) ([]byte, error) note 2nd parameter (*http.request) required appengine (in order able create context), in implementation local env not used (can nil).
an elegant solution can take advantage of http.client type available in both standard environment , in appengine, , can used http request. http.client value can acquired differently on appengine, once have http.client value, can proceed same way. have common code receives http.client , can rest.
example implementation can this:
url_local.go:
// +build !appengine package mypackage import ( "net/http" ) func geturl(url string, r *http.request) ([]byte, error) { // local geturl implementation return getclient(url, &http.client{}) } url_gae.go:
// +build appengine package mypackage import ( "google.golang.org/appengine" "google.golang.org/appengine/urlfetch" "net/http" ) func geturl(url string, r *http.request) ([]byte, error) { // appengine geturl implementation ctx := appengine.newcontext(r) c := urlfetch.client(ctx) return getclient(url, c) } url_common.go:
// no build constraint: common code package mypackage import ( "net/http" ) func getclient(url string, c *http.client) ([]byte, error) { // implementation both local , appengine resp, err := c.get(url) if err != nil { return nil, err } defer resp.body.close() body, err := ioutil.readall(resp.body) if err != nil { return nil, err } return body, nil }
Comments
Post a Comment