Go language standard librarynet/http
The package is very excellent and provides a very complete implementation of HTTP client and server. You can build a very simple HTTP server with just a few lines of code. Almost all web frameworks in the go language are encapsulation and modifications to existing http packages. Therefore, it is very important to master the http package before learning other frameworks.
HTTP Server
Let's first introduce the followingnet/http
Use of packages, through()
and()
Two functions can easily create a simple Go web server, the sample code is as follows:
package main import ( "fmt" "net/http" ) func helloHandler(w , r *) { (w, "Hello, World!") } func main() { ("/hello", helloHandler) ("Server starting on port 8080...") (":8080", nil) }
Routing processing
The http package provides two routing registration methods:
Processor Function (HandlerFunc):(pattern string, handler func(ResponseWriter, *Request))
func helloHandler(w , r *) { (w, "Hello, World!") } ("/hello", helloHandler)
This form is the simplest and most direct, and is suitable for handling simple routing logic.The function will be converted to
HandlerFunc
Type, it implementsHandler
interface.
Processor object (Handler):(pattern string, handler Handler)
type CounterHandler struct { count int } func (h *CounterHandler) ServeHTTP(w , r *) { ++ (w, "Visitor count: %d", ) } handler := &CounterHandler{} ("/counter", handler)
ServeMux Routing
It is a multiplexer (router) provided by Go by default, which implements
Handler
Interface can be regarded as an advanced router manager. It works by:
- When registering a route, store the path pattern and handler in the internal mapping
- When receiving a request, find the corresponding processor according to the longest matching principle.
- If the exact match is not found, it will try to find the path with slashes
- In the end, no results are found, and an error of 404 will be returned.
mux := () ("/products/", productsHandler) ("/articles/", articlesHandler) ("/", indexHandler)
Although this routing design is simple, it is sufficient for RESTful APIs and traditional web applications. For more complex needs, third-party routing libraries such as gorilla/mux can be considered.
HTTP Client
GET Request
resp, err := ("") if err != nil { // Handle errors} defer () body, err := () if err != nil { // Handle errors} (string(body))
POST request
data := {} ("key", "value") resp, err := ("/form", data) if err != nil { // Handle errors} defer () // Processing response...
Custom requests
req, err := ("GET", "", nil) if err != nil { // Handle errors} ("Authorization", "Bearer token123") ("Content-Type", "application/json") client := &{ Timeout: * 10, } resp, err := (req) if err != nil { // Handle errors} defer () // Processing response...
Middleware mode
Middleware is the key model for building modular HTTP services. Go's middleware is essentially a processor's wrapper function, which can add cross-cutting concern function without modifying the core business logic.
Basic middleware structure
func loggingMiddleware(next ) { return (func(w , r *) { start := () // Call the next processor (w, r) // Record request log ( "%s %s %s %v", , , , (start), ) }) }
The workflow for this model is:
- The middleware receives a processor as a parameter
- Return a new processor
- The new processor adds additional functionality before and after executing the original logic
Middleware chain
Multiple middleware can form a processing chain in series:
func authMiddleware(next ) { return (func(w , r *) { if !isAuthenticated(r) { (w, "Unauthorized", ) return } (w, r) }) } func main() { mux := () ("/secure", secureHandler) // Build middleware chain handler := loggingMiddleware(authMiddleware(mux)) (":8080", handler) }
The execution order of middleware is from the outside to the inside, that is, the middleware registered first and then execute. In the above example, the request will be logged first and then authenticated.
Context delivery
Middleware is often used to pass values between requests, and should be used at this time.:
func requestIDMiddleware(next ) { return (func(w , r *) { // Generate a unique request ID requestID := ().String() // Create a new context and store the request ID ctx := ((), "requestID", requestID) // Set response header ().Set("X-Request-ID", requestID) // Continue processing with new context (w, (ctx)) }) } // Get the request ID in the processorfunc handler(w , r *) { requestID := ().Value("requestID").(string) (w, "Request ID: %s", requestID) }
This method is thread-safe, avoids the problem of global variables, and is a recommended way to handle data transfer between requests in Go.
References:
Golang Chinese learning document Standard library http package
This is the article about the detailed explanation of the use of the Go language net/http package. This is the end of this article. For more related contents of the use of the Go language net/http package, please search for my previous articles or continue browsing the following related articles. I hope everyone will support me in the future!