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
