Adding Logging and Error Handling Middleware to Your Go API

Patricia Arquette
Release: 2024-10-05 14:07:02
Original
482 people have browsed it

Adding Logging and Error Handling Middleware to Your Go API

Quick Note: If you checked out my previous post on JWT authentication and noticed some rendering issues, those have now been fixed! Be sure to give it another look because these examples build on top of that tutorial. :)

Alright folks, we’ve got our Go API running, we’ve added JWT authentication, and we’ve even connected it to a PostgreSQL database. But we’re not done yet! This week, we’re going to take things up a notch and make our API smarter and more developer-friendly by adding custom middleware for logging and error handling.

What’s Middleware Again? ?

Middleware is like a bouncer at your favorite club—it intercepts requests before they hit your API endpoints. You can have middleware that checks authentication (like we did with JWT), logs information, or handles errors when things go wrong.

Today, we’re going to build middleware that:

  • Logs: Every incoming request, so we know who’s knocking on our API’s door.
  • Handles Errors: Gracefully, so your users don’t see those ugly 500 errors.

Let’s dive into it!


Step 1: Creating a Logging Middleware ?

Logging is your best friend when it comes to debugging and understanding what’s happening in your API. We’re going to create a middleware that logs every request that comes through—method, URL, and time taken.


func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        // Log the method and the requested URL
        log.Printf("Started %s %s", r.Method, r.URL.Path)

        // Call the next handler in the chain
        next.ServeHTTP(w, r)

        // Log how long it took
        log.Printf("Completed in %v", time.Since(start))
    })
}


Copy after login

For those who are interested in diving deeper into logging middleware, I recommend checking out Matt Silverlock’s fantastic guide on writing logging middleware in Go. He breaks down how to structure reusable middleware for various use cases like authentication, tracing, and of course, logging!

Step 2: Error Handling Middleware ?

Let’s talk about errors. Errors happen, right? But rather than letting them cause a crash or send a vague error message, let’s handle them gracefully.


func errorHandlingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                // Log the error and send a user-friendly message
                log.Printf("Error occurred: %v", err)
                http.Error(w, "Internal Server Error", http.StatusInternalServerError)
            }
        }()
        next.ServeHTTP(w, r)
    })
}


Copy after login

Step 3: Integrating Middleware in Your API ?

Now that we’ve built our logging and error-handling middleware, let’s hook them up to our API. We’ll apply them globally so every request gets logged and errors are caught.


func main() {
    db = connectDB()
    defer db.Close()

    r := mux.NewRouter()

    // Apply middleware globally
    r.Use(loggingMiddleware)
    r.Use(errorHandlingMiddleware)

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")
    r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}


Copy after login

Step 4: Testing It Out ?

To make sure everything’s working, start up your API:


go run main.go


Copy after login

Now, try hitting any of your endpoints (like /books) and check your terminal. You should see logs like:


Started GET /books
Completed in 1.2ms


Copy after login

And if there’s an error, you’ll see:


Error occurred: some error details


Copy after login

But your user will only see a clean "500 Internal Server Error" message. ?


Why Is This Important?

  1. Logging helps you track down bugs and monitor the behavior of your API. If something goes wrong, you’ll know exactly which endpoint was hit and how long the request took.

  2. Error Handling prevents your API from crashing when something unexpected happens. Instead, it recovers gracefully and sends a clean error message to the client.


What’s Next?

Next time, we’ll take things to the next level and dockerize our Go API! This will make your app portable and ready for deployment on any machine or cloud service. Get ready for some container magic! ?

The above is the detailed content of Adding Logging and Error Handling Middleware to Your Go API. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template