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 appengine
will built app engine sdk , ignored go tool. conversely, files specify
// +build !appengine
are 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