AppEngine/Go: urlfetch vs http.Get, etc - google-app-engine

Is it necessary to use urlfetch under AppEngine? I'd like to write a generic client to use with one of my services, but, if urlfetch is required from AppEngine, how can I write a generic client for use both from outside AppEngine (for the public) and inside AppEngine (for my other services) without having to write two different versions or passing some kind of factory that produces the right implementation?

The application should pass an http.Client to your generic client. It can either be a parameter to the function or passed through a context as done in the oauth2 package.
If the application does not provide a http.Client through one of these mechanisms (nil arg or no value in context), then use the default client.

Related

google managed-VMs specify instance in URL

I use google managed-VMs. My module has several instances. I need to perform a HTTP call on each of these instances. Hence, I would like to know if there is a way to specify the recipient instance in the URL.
For instance I tried: http://<instance-name>.<module-name>.<project-name>.appspot.com/ without success.
You're missing a <version-name> in there:
http://<instance-name>.<version-name>.<module-name>.<project-name>.appspot.com
See https://cloud.google.com/appengine/docs/python/modules/#Python_Application_hierarchy for more details (this is the page for Python, but it applies across-the-board.

http.DefaultTransport and http.DefaultClient are not available in AppEngine, but a lib uses them

I'm using a library (gotwilio) that makes http requests to a server using a http.Client object:
client := &http.Client{}
However this fails on appengine with the following error message:
http.DefaultTransport and http.DefaultClient are not available in App Engine
This makes sense. However since the lib is using these directly there is no way for me to tell the library to use the urlfetch based transport that appengine provides.
Is there a way to make &http.Client{} always return a client that works with urlfetch.... In java this is also possible on appengine. (URLConnection just works)
Sadly no, OTOH you can just copy the library, change func (twilio *Twilio) post in github.com/sfreiberg/gotwilio/gotwilio.go and use your local copy until it's implemented properly.

How could I manage the App Engine Go runtime context to avoid App Engine lock-in?

I'm writing a Go application to run on App Engine's Go runtime.
I notice that pretty much any operation which uses an App Engine service (such as Datastore, Mail, or even Capabilities) requires that you pass it an instance of appengine.Context which must be retrieved using the function appengine.NewContext(req *http.Request) Context.
While I am writing this app for App Engine, I want to be able to move it to some other platform (possibly one which doesn't support any of the App Engine API) easily and quickly if I should so choose.
So, I'm abstracting away the actual interaction with App Engine services and API's by writing little wrappers around any App-Engine-specific interaction (including request handling functions). With this approach, if I ever do wish to move to a different platform, I'll just rewrite those specific modules which tie my application to App Engine. Easy and straightforward.
The only problem is that appengine.Context object. I can't pass it down from my request handlers through my layers of logic to the modules which handle these API's without tying pretty much all of my code to App Engine. I could pass the http.Request object from which the appengine.Context object can be derived, but that would require coupling things that probably shouldn't be coupled. (I think it's best practice for none of my application to even know it's a web application except those portions specifically dedicated to handling HTTP requests.)
The first solution that sprang to mind was to just create a persistent variable in some module. Something like this:
package context
import (
"appengine"
)
var Context appengine.Context
Then, in my request handlers, I can set that variable with context.Context = appengine.NewContext(r) and in the modules that directly use App Engine services, I can fetch the context by accesing context.Context. None of the intervening code would need to know of the appengine.Context object's existence. The only problem is that "multiple requests may be handled concurrently by a given instance", which can lead to race conditions and unexpected behavior with this plan. (One request sets it, another sets it, the first one accesses it and gets the wrong appengine.Context object.)
I could in theory store the appengine.Context to datastore, but then I'd have to pass some request-specific identifier down the logic layers to the service-specific modules identifying which appengine.Context object in datastore is the one for the current request, which would again couple things I don't think should be coupled. (And, it would increase my application's datastore usage.)
I could also pass the appengine.Context object down the whole logic chain with the type interface{} the whole way and have any module which doesn't need the appengine.Context object ignore it. That would avoid tying most of my application to anything specific. That also seems highly messy, however.
So, I'm at a bit of a loss how to cleanly ensure the App-Engine-specific modules which need the appengine.Context object can get it. Hopefully you folks can give me a solution I have yet to think of myself.
Thanks in advance!
This is tricky because your self-imposed scoping rule (which is a sensible one) means not passing a Context instance around, and there is nothing similar to Java's ThreadLocal to achieve the same ends by sneaky means. That's actually a Good Thing, really.
Context combines logging support (easy) with a Call to appengine services (not easy). There are I think ten appengine functions that need a Context. I can't see any clean solution other than wrapping all of these behind your own facade.
There is one thing that can help you - you can include a configuration file with your app that indicates whether it's in GAE or otherwise, using a flag of some sort. Your global boolean need only store this flag (not a shared context). Your facade functions can then consult this flag when deciding whether to use NewContext(r) to obtain the Context to access GAE services, or use a lookalike structure to access your own substitute services.
Edit: As a final remark, when you solve this may I invite you to share how you did it, possibly even with an open-source project? Cheeky of me to ask, but if you don't ask... ;-)
I (hopefully) solved this issue by wrapping my request handlers (in this example one called "realHandler") like this:
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ds := NewDataStore(r)
realHandler(w, r, ds)
})
NewDataStore creates a DataStore, which is a simple wrapper that abstracts the GAE datastore. It has an unexposed field where it stores the context:
type DataStore struct {
c appengine.Context
}
func NewDataStore(req *http.Request) *DataStore {
return &DataStore{appengine.NewContext(req)}
}
Within the request handler, I can just access the abstracted datastore when I need it without worrying about the GAE context, which has already been set:
func realHandler(w http.ResponseWriter, req *http.Request, db *DataStore) {
var s SomeStruct{}
key, err := db.Add("Structs", &s)
...
}
Particularly in case of Datastore you should be able to reuse the same appengine.Context among different requsts. I haven't tried to do it myself but that's the way an alternative API for Datastore called goon works:
Goon differs from the datastore package in various ways: it remembers the appengine Context, which need only be specified once at creation time
The fact that storage should depend on HTTP request sounds ridiculous by the way. I don't think Datastore depends on a particular request in the usual sense. Most probably, it's needed to identify a particular Google App Engine application which obviously stays the same from request to request. My speculations are based on quick skim over the source code of google.golang.org/appengine.
You may do similar observations in regard of the other Google App Engine APIs. Of cause all the details could be implementation specific and I'd performed more deep research before actually using those observations in a real application.
It's worth to note that Go team introduced a golang.org/x/net/context package.
Later on the context was made available in Managed VMs, the repo is here. The documentation states:
This repository supports the Go runtime on App Engine, including both classic App Engine and Managed VMs. It provides APIs for interacting with App Engine services. Its canonical import path is google.golang.org/appengine.
What it means is that you could easily write another packages out of dev environment depending on appengine.
In particular it becomes very easy to wrap around packages like appengine/log (trivial log wrapper example).
But even more important this allows one to create handlers in a form:
func CoolHandler(context.Context, http.ResponseWriter, *http.Request)
There's an article about a context package on Go blog here. I wrote about using context here. If you decide to use the handler with context passing around it's good to create context for all requrests in one place. You can do it by using non standard requrest router like github.com/orian/wctx.
I handled this by wrapping appengine.NewContext behind an interface, and provide different implementations through different packages. That way, I don't have to link GAE into any binaries where it isn't used:
type Context interface {
GetHTTPContext(r *http.Request) context.Context
}
I provide a method for subpackages to register themselves when imported for side effects, sort of database/sql-style:
var _context Context
func Register(c Context) {
_context = c // Nil checking, double registration checking omitted for brevity
}
I start with a default implementation for vanilla, non-GAE binaries, that simply grabs the existing context:
var _context Context = &defaultContext{} // use this by default
type defaultContext struct {}
func (d *defaultContext) GetHTTPContext(r *http.Request) context.Context {
return r.Context()
}
Then I put an App Engine implementation in a package mything/context/appengine:
import(
ctx "mything/context"
)
type aecontext struct {}
func (a *aecontext) GetHTTPContext(r *http.Request) context.Context {
return appengine.NewContext(r)
}
func init() {
ctx.Register(&aecontext{})
}
Then my GAE binary can pull in the subpackage, which registers itself in init:
import(
_ "mything/context/appengine"
)
And my app code uses GetHTTPContext(r) to get an appropriate context to pass into dependencies.

httplib.HTTPConnection in Google AppEngine

I use httplib.HTTPConnection within my app. Do I really need to provide host parameter in httplib.HTTPConnection constructor? If so, why? (I mean, I know that it's a mandatory parameter, but I wonder if I could specify None or empty string) And is there any global constant in Google AppEngine and in development server which I can use within my app in order to omit explicitly defined host.
If you leave it out of the constructor, how will the other methods know where to send their messages?
The address/name of the server you're connecting to is the parameter for the HTTPConnection, the URI on that server is what goes into request.
From the python documentation (which is the basis for AppEngine)
h1 = httplib.HTTPConnection(host[, port[, strict[, timeout[, source_address]]]])
h1.request(method, url[, body[, headers]])
[edit]
Remember, it may not always be you who is responsible for this code. Also, why complicate things by including so much more information in the URI when you're (for example) making calls to numerous URI's on the same website?
[/edit]

GWT: Where (how) to define POJOs to make em available for client and server? (and to use datastore on serverside)

I try to get an application running which should interact with a server via RPC (JDO in Google DataStore). So I defined a persistent POJO on the server-side to get it put in the datastore via the PersistenceManager (as shown in the gwt rpc tuts). Everything works fine. But I am not able to receive the callback POJO on the client side because the POJO is only defined on server-side. How can I realize it, that the client knows that kind of object??
(sry for my bad english)
Lars
Put your POJOs in a separate package/directory (e.g. com.example.common) and then add source declaration to your GWT module descriptor (xyz.gwt.xml):
<source path="common"/> //relative to your xyz.gwt.xml location
GWT compiler will then also compile POJOs and they will be seen by your other GWT code.
Edited:
#Lars - now I understand your problem. As I see it you have several options:
If possible use Objectify instead of JDO. Objectify uses pure POJOs and they play nicely with GWT. I use this in my projects. One nice thing that Objectify gives you is #PostLoad & # PrePersist on methods to run some code before/after POJOs are loaded/saved to datastore. I use this to handle serialization of GeoPoint for instance.
Use JDO and make copies of your domain classes. This is a pain but it would work. Use 'transient' java keyword in your server JDO classes to exclude fields you do not want to RPC.
Edit #2: There is a third option that you might prefer:
Create "fake" JDO annotation classes using super-sourcing. This is a common technique to replace classes with a GWT version. Described here: http://fredsa.allen-sauer.com/2009/04/1st-look-at-app-engine-using-jdo.html
You can use DTO(stackoverflow, moar) for transferring data to client.
Basic sample here (method getTenLatestEntries() in your case).
Or you can use some third-party libraries like objectify and stop worry about making DTO`s.

Resources