Go Gorilla Mux
To integrate APIToolkit with golang web services, we employ an SDK named the golang client for APIToolkit. This SDK oversees the incoming traffic, bundles the requests, and then forwards them to the APItoolkit servers. In this guide, we’ll delve into a detailed procedure to integrate the APIToolkit within our Go Gorilla mux web service.
Design Considerations
- Internally, the SDK leverages google cloud pubsub via grpc, ensuring that your data is efficiently relayed to APIToolkit for processing.
- Managing live traffic in this fashion enables:
- APIToolkit to conduct real-time analysis, anomaly detection, and monitoring of your APIs.
- Users to actively inspect their API through the api log explorer.
Create an Account or Sign In to APIToolkit to Generate Key
- Sign up / Sign in to the API dashboard
- Create a project
- Generate an API key for your project, and include a brief description of your work. And to prevent losing your key after it has been generated, remember to make a copy of it.
Integrate with Gorilla Mux in Go
Assuming you’ve already set up Go and wish to integrate with Gorilla Mux:
a. Install necessary packages:
go get -u github.com/gorilla/mux
b. Create a new Go file, for instance, main.go
c. Set up your Gorilla Mux router:
package main
import (
"github.com/gorilla/mux"
"net/http"
)
func main() {
r := mux.NewRouter()
// Define your routes here...
http.Handle("/", r)
http.ListenAndServe(":8080", r)
}
d. Integrate with APITOOLKIT:
Let’s go ahead and write the code to initialize apitoolkit
with gorilla/mux
:
package main
import (
"context"
"net/http"
"github.com/gorilla/mux"
apitoolkit "github.com/apitoolkit/apitoolkit-go"
)
func main() {
ctx := context.Background()
// Initialize the client using your generated apikey
apitoolkitClient, err := apitoolkit.NewClient(ctx, apitoolkit.Config{APIKey: "<APIKEY>"})
if err != nil {
panic(err)
}
r := mux.NewRouter()
// Register middleware
r.Use(apitoolkitClient.GorillaMuxMiddleware)
r.HandleFunc("/{slug}/test",func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
})
http.ListenAndServe(":8080", r)
}
Replace "YOUR_GENERATED_API_KEY"
with your actual API key.
Test the Integration
This code sets up a basic HTTP server using gorilla/mux
and integrates the apitoolkit
middleware. When you run this code and make a request to http://localhost:8080/{some_slug}/test
, it should go through the apitoolkit
middleware before responding with “ok”.
Redacting Sensitive Fields with Gorilla Mux and APIToolkit
It’s possible to mark fields as redacted directly on the API Toolkit dashboard. However, you also have the option to handle redaction on the client side. By opting for client-side redaction, you’re ensuring these sensitive fields won’t leave your server, enhancing data privacy.
Suppose you’re dealing with a request body like:
{
"user": {
"id": 123456789,
"name": "Precious John",
"password": "secretpassword123",
"creditCard": {
"number": "1234567890123456",
"expiry": "12/25"
}
}
}
To redact the password
and credit card number
fields, you would configure the apitoolkit
config struct in this manner:
package main
import (
"net/http"
"github.com/gorilla/mux"
apitoolkit "github.com/apitoolkit/apitoolkit-go"
)
func main() {
r := mux.NewRouter()
apitoolkitCfg := apitoolkit.Config{
RedactHeaders: []string{"Content-Type", "Authorization", "Cookies"}, // Redacting both request and response headers
RedactRequestBody: []string{"$.user.password", "$.user.creditCard.number"},
RedactResponseBody: []string{"$.message.error"},
APIKey: "<APIKEY>",
}
// Initialize the APIToolkit client using your generated API key
apitoolkitClient, _ := apitoolkit.NewClient(apitoolkitCfg)
r.Use(apitoolkitClient.GorillaMuxMiddleware)
r.HandleFunc("/:slug/test", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}).Methods("POST")
http.Handle("/", r)
http.ListenAndServe(":8080", r)
}
It’s pivotal to note that while the RedactHeaders
config field will take the header names (which are case insensitive), RedactRequestBody
and RedactResponseBody
work with JSONPath strings.
Using JSONPath allows for flexibility when determining which fields in your responses are sensitive. This configuration is global and impacts all endpoint requests and responses. To get a better grasp of JSONPath and how to draft these queries, look into: JSONPath Cheatsheet
Outgoing Requests
To monitor outgoing HTTP requests from your Go application, you can replace the default HTTP client transport with a custom roundtripper. This allows you to capture and send copies of all incoming and outgoing requests to an apitoolkit server for monitoring and analysis.
Example
package main
import (
"net/http"
"github.com/gorilla/mux"
apitoolkit "github.com/apitoolkit/apitoolkit-go"
)
func main() {
apitoolkitClient, err := apitoolkit.NewClient(context.Background(), apitoolkit.Config{APIKey: "<API KEY>"})
if err != nil {
panic(err)
}
handlerFn := func(w http.ResponseWriter, r *http.Request) {
HTTPClient := http.DefaultClient
HTTPClient.Transport = client.WrapRoundTripper(
r.Context(), HTTPClient.Transport,
WithRedactHeaders([]string{}),
)
_, _ = HTTPClient.Get("http://localhost:3000/test-outgoing")
w.WriteHeader(http.StatusAccepted)
w.Write([]byte("Hello world"))
}
r := mux.NewRouter()
r.Use(client.GorillaMuxMiddleware)
r.HandleFunc("/:slug/test", handlerFn).Methods(http.MethodPost)
}
The provided code demonstrates how to set up the custom roundtripper to replace the default HTTP client’s transport. The resulting HTTP client, HTTPClient
, is configured to send copies of all incoming and outgoing requests to the apitoolkit servers. You can use this modified HTTP client for any HTTP requests you need to make from your server, ensuring they are monitored by apitoolkit.
Report Errors
If you’ve used sentry, or bugsnag, or rollbar, then you’re already familiar with this usecase.
But you can report an error to apitoolkit. A difference, is that errors are always associated with a parent request, and helps you query and associate the errors which occured while serving a given customer request. To request errors to APIToolkit use call the ReportError
method of apitoolkit
not the client returned by apitoolkit.NewClient
with the request context and the error to report
Example:
Gorilla mux
import (
//... other imports
apitoolkit "github.com/apitoolkit/apitoolkit-go"
)
func main() {
r := mux.NewRouter()
ctx := context.Background()
apitoolkitClient, err := apitoolkit.NewClient(ctx, apitoolkit.Config{APIKey: "<API_KEY>"})
if err != nil {
panic(err)
}
r.Use(apitoolkitClient.GorillaMuxMiddleware)
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := os.Open("non-existing-file.json")
if err != nil {
// Report the error to apitoolkit
apitoolkit.ReportError(r.Context(), err)
}
fmt.Fprintln(w, "Hello, World!")
})
server := &http.Server{Addr: ":8080", Handler: r}
err = server.ListenAndServe()
if err != nil {
fmt.Println(err)
}
}
Next Steps
- Deploy your application or initiate test HTTP requests to your service.
- Visit the API log explorer or the Endpoints tab on the APIToolkit dashboard. Here, you can confirm if your test request was handled properly.
- Enjoy having our API comanage your backends and APIs with you.