Fun with golang, Google Maps api, and proxying requests
- Posted by Michael MacDonald
- on Aug, 31, 2017
- in Go
- Blog No Comments.
I admire published api code that is thoroughly thought through. Recently I have been working with the Google Maps API in golang and have found that they set it up to allow one to pass in an net/http/client variable which means that it is possible to create a http client which sends the requests via a proxy (such as Fiddle) in order to debug and diagnose challenges with the code.
package main import ( "net/http" "net/url" "crypto/tls" "context" "googlemaps.github.io/maps" "github.com/davecgh/go-spew/spew" ) func main() { APIKey := "[Google API KEY]" proxyURL, _ := url.Parse("http://localhost:9999") tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, Proxy: http.ProxyURL(proxyURL), } client := &http.Client{Transport: tr} c, _ := maps.NewClient( maps.WithAPIKey(APIKey), maps.WithHTTPClient(client), ) r := &maps.GeocodingRequest{ Address: "1600 Pennsylvania Ave NW", Region: "us", } resp, e := c.Geocode(context.Background(), r) spew.Dump(resp,e) }
which when executed would return:
$ go run main.go ([]maps.GeocodingResult) (len=1 cap=4) { (maps.GeocodingResult) { AddressComponents: ([]maps.AddressComponent) (len=7 cap=9) { (maps.AddressComponent) { LongName: (string) (len=29) "Pennsylvania Avenue Northwest", ShortName: (string) (len=19) "Pennsylvania Ave NW", Types: ([]string) (len=1 cap=4) { (string) (len=5) "route" } }, (maps.AddressComponent) { LongName: (string) (len=4) "1600", ShortName: (string) (len=4) "1600", Types: ([]string) (len=1 cap=4) { (string) (len=13) "street_number" } }, (maps.AddressComponent) { LongName: (string) (len=20) "Northwest Washington", ShortName: (string) (len=20) "Northwest Washington", Types: ([]string) (len=2 cap=4) { (string) (len=12) "neighborhood", (string) (len=9) "political" } }, (maps.AddressComponent) { LongName: (string) (len=10) "Washington", ShortName: (string) (len=10) "Washington", Types: ([]string) (len=2 cap=4) { (string) (len=8) "locality", (string) (len=9) "political" } }, (maps.AddressComponent) { LongName: (string) (len=20) "District of Columbia", ShortName: (string) (len=2) "DC", Types: ([]string) (len=2 cap=4) { (string) (len=27) "administrative_area_level_1", (string) (len=9) "political" } }, (maps.AddressComponent) { LongName: (string) (len=13) "United States", ShortName: (string) (len=2) "US", Types: ([]string) (len=2 cap=4) { (string) (len=7) "country", (string) (len=9) "political" } }, (maps.AddressComponent) { LongName: (string) (len=5) "20500", ShortName: (string) (len=5) "20500", Types: ([]string) (len=1 cap=4) { (string) (len=11) "postal_code" } } }, FormattedAddress: (string) (len=51) "1600 Pennsylvania Ave NW, Washington, DC 20500, USA", Geometry: (maps.AddressGeometry) { Location: (maps.LatLng) 38.8976633,-77.0365739, LocationType: (string) (len=7) "ROOFTOP", Bounds: (maps.LatLngBounds) 38.8973063,-77.03795749999999|38.8979044,-77.0355124, Viewport: (maps.LatLngBounds) 38.8962604197085,-77.0380839302915|38.8989583802915,-77.03538596970849, Types: ([]string) <nil> }, Types: ([]string) (len=3 cap=4) { (string) (len=13) "establishment", (string) (len=17) "point_of_interest", (string) (len=7) "premise" }, PlaceID: (string) (len=27) "ChIJGVtI4by3t4kRr51d_Qm_x58" } } (interface {}) <nil>
In the proxy we see the request:
GET https://maps.googleapis.com/maps/api/geocode/json?address=1600+Pennsylvania+Ave+NW&key=[REDACTED]®ion=us HTTP/1.1 Host: maps.googleapis.com User-Agent: GoogleGeoApiClientGo/0.1 Accept-Encoding: gzip
with the corresponding response:
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Thu, 31 Aug 2017 18:53:31 GMT Expires: Fri, 01 Sep 2017 18:53:31 GMT Cache-Control: public, max-age=86400 Vary: Accept-Language Access-Control-Allow-Origin: * Server: mafe Content-Length: 2319 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,35" { "results" : [ { "address_components" : [ { "long_name" : "Pennsylvania Avenue Northwest", "short_name" : "Pennsylvania Ave NW", "types" : [ "route" ] }, { "long_name" : "1600", "short_name" : "1600", "types" : [ "street_number" ] }, { "long_name" : "Northwest Washington", "short_name" : "Northwest Washington", "types" : [ "neighborhood", "political" ] }, { "long_name" : "Washington", "short_name" : "Washington", "types" : [ "locality", "political" ] }, { "long_name" : "District of Columbia", "short_name" : "DC", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "United States", "short_name" : "US", "types" : [ "country", "political" ] }, { "long_name" : "20500", "short_name" : "20500", "types" : [ "postal_code" ] } ], "formatted_address" : "1600 Pennsylvania Ave NW, Washington, DC 20500, USA", "geometry" : { "bounds" : { "northeast" : { "lat" : 38.8979044, "lng" : -77.0355124 }, "southwest" : { "lat" : 38.8973063, "lng" : -77.03795749999999 } }, "location" : { "lat" : 38.8976633, "lng" : -77.03657389999999 }, "location_type" : "ROOFTOP", "viewport" : { "northeast" : { "lat" : 38.8989583802915, "lng" : -77.03538596970849 }, "southwest" : { "lat" : 38.8962604197085, "lng" : -77.03808393029151 } } }, "place_id" : "ChIJGVtI4by3t4kRr51d_Qm_x58", "types" : [ "establishment", "point_of_interest", "premise" ] } ], "status" : "OK" }
Related
Comments & Responses
Recent Posts
- The shape of structured data
- Writing very small executable
- The challenge of type asserting []interface{} to string slices.
- Serializing/Deserializing a complex GO struct to store externally (i.e. in a database, redis, or text file)
- Fun with golang, Google Maps api, and proxying requests