9 Composition patterns

 

This chapter covers

  • Composition patterns and functional programming techniques.
  • Field embedding and method forwarding to provide extra functionality.
  • Optional interfaces, method hiding issues, and type assertions.
  • Using Context to propagate values across packages APIs.
  • Implementing a custom slog.Handler to log extra log attributes.
  • Interface wrapping techniques to change existing behavior.
  • Effectively using anonymous interfaces for extracting behavior.

Lastly, we implemented Bite's link service. We discussed structuring multiple packages and developed a REST API over HTTP. In this chapter, we'll extend our project with additional packages focusing on middleware, logging, Context value propagation, and composition.

We'll discuss functional compositional patterns to demonstrate how to design packages that offer reusable and composable functionality, showcasing HTTP middleware. We'll then dive into propagating trace IDs and explain how to write custom log handlers. Lastly, we'll discover a handler chaining pattern for writing robust and convenient HTTP handlers.

"If C++ and Java are about type hierarchies and the taxonomy of types, Go is about composition."

— Rob Pike, from his "Less is exponentially more" article

9.1 Middleware pattern

9.1.1 What is HTTP middleware?

9.1.2 Usage

9.1.3 Practice

9.1.4 Integration

9.2 Logging responses

9.2.1 Measuring durations

9.2.2 Response recording

9.2.3 Integration

9.3 Interceptor pattern

9.3.1 Field embedding

9.3.2 Capturing and saving

9.3.3 Integration

9.4 Optional interface pattern

9.4.1 Type asserting for optional functionality

9.4.2 Unwrapping all the way down

9.4.3 Unwrap

9.5 Context value propagation pattern

9.5.1 Generating, storing, and retrieving

9.5.2 Middleware

9.5.3 Wrapping slog handlers

9.5.4 Implementing a slog.Handler

9.5.5 Integration

9.6 Handler chaining pattern

9.6.1 Chainable handlers

9.6.2 Response handlers

9.6.3 Responder

9.6.4 Integration

9.7 Encoding and decoding

9.7.1 Encoding JSON

9.7.2 Decoding JSON

9.7.3 Speaking JSON

9.8 Wrapping and unwrapping

9.8.1 Safeguarding against DoS attacks