Exemples de Réseau Web Go

Exemples de réseau Web Go incluant les requêtes HTTP, les serveurs HTTP et les sockets TCP

Key Facts

Category
Go
Items
3
Format Families
json

Sample Overview

Exemples de réseau Web Go incluant les requêtes HTTP, les serveurs HTTP et les sockets TCP This sample set belongs to Go and can be used to test related workflows inside Elysia Tools.

💻 Requêtes HTTP go

🟢 simple ⭐⭐

Envoyer des requêtes GET/POST avec en-têtes, paramètres de requête et gestion des requêtes/réponses

⏱️ 20 min 🏷️ go, web, networking
Prerequisites: Basic Go, net/http package
// Web Go HTTP Requests Examples
// Sending HTTP GET/POST requests with proper handling

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
)

// 1. Simple GET Request

// SimpleGet performs a simple HTTP GET request
func SimpleGet(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("GET request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}

	return string(body), nil
}

// SimpleGetExample demonstrates simple GET request
func SimpleGetExample() {
	fmt.Println("--- Simple GET Request ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"
	body, err := SimpleGet(url)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 2. GET Request with Headers

// GetWithHeaders performs GET request with custom headers
func GetWithHeaders(url string, headers map[string]string) (string, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}

	// Add headers
	for key, value := range headers {
		req.Header.Set(key, value)
	}

	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	return string(body), nil
}

// GetWithHeadersExample demonstrates GET with headers
func GetWithHeadersExample() {
	fmt.Println("\n--- GET with Headers ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"
	headers := map[string]string{
		"Accept":        "application/json",
		"User-Agent":    "MyGoApp/1.0",
		"Authorization": "Bearer token123",
	}

	body, err := GetWithHeaders(url, headers)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 3. GET Request with Query Parameters

// GetWithQueryParams performs GET with query parameters
func GetWithQueryParams(baseURL string, params map[string]string) (string, error) {
	// Build URL with query parameters
	u, err := url.Parse(baseURL)
	if err != nil {
		return "", err
	}

	query := u.Query()
	for key, value := range params {
		query.Set(key, value)
	}
	u.RawQuery = query.Encode()

	url = u.String()

	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("GET request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	return string(body), nil
}

// GetWithQueryParamsExample demonstrates GET with query parameters
func GetWithQueryParamsExample() {
	fmt.Println("\n--- GET with Query Parameters ---")

	baseURL := "https://jsonplaceholder.typicode.com/posts"
	params := map[string]string{
		"userId": "1",
		"_limit": "5",
	}

	body, err := GetWithQueryParams(baseURL, params)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 4. POST Request with JSON Body

// PostJSON sends a POST request with JSON body
func PostJSON(url string, data map[string]interface{}) (string, error) {
	jsonData, err := json.Marshal(data)
	if err != nil {
		return "", fmt.Errorf("error marshaling JSON: %v", err)
	}

	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return "", fmt.Errorf("POST request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}

	return string(body), nil
}

// PostJSONExample demonstrates POST with JSON
func PostJSONExample() {
	fmt.Println("\n--- POST JSON Request ---")

	url := "https://jsonplaceholder.typicode.com/posts"
	data := map[string]interface{}{
		"title":  "Test Post",
		"body":   "This is a test post",
		"userId": 1,
	}

	body, err := PostJSON(url, data)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 5. POST Request with Form Data

// PostForm sends a POST request with form data
func PostForm(url string, formData map[string]string) (string, error) {
	// Build form data
	values := url.Values{}
	for key, value := range formData {
		values.Set(key, value)
	}

	resp, err := http.PostForm(url, values)
	if err != nil {
		return "", fmt.Errorf("POST form request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	return string(body), nil
}

// PostFormExample demonstrates POST with form data
func PostFormExample() {
	fmt.Println("\n--- POST Form Request ---")

	url := "https://jsonplaceholder.typicode.com/posts"
	formData := map[string]string{
		"title":  "Test Form",
		"body":   "Form data content",
		"userId": "1",
	}

	body, err := PostForm(url, formData)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 6. PUT Request

// PutJSON sends a PUT request with JSON body
func PutJSON(url string, data map[string]interface{}) (string, error) {
	jsonData, err := json.Marshal(data)
	if err != nil {
		return "", fmt.Errorf("error marshaling JSON: %v", err)
	}

	req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}

	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("PUT request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	return string(body), nil
}

// PutJSONExample demonstrates PUT request
func PutJSONExample() {
	fmt.Println("\n--- PUT Request ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"
	data := map[string]interface{}{
		"id":     1,
		"title":  "Updated Post",
		"body":   "Updated content",
		"userId": 1,
	}

	body, err := PutJSON(url, data)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// 7. DELETE Request

// DeleteResource sends a DELETE request
func DeleteResource(url string) (int, error) {
	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return 0, err
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return 0, fmt.Errorf("DELETE request failed: %v", err)
	}
	defer resp.Body.Close()

	return resp.StatusCode, nil
}

// DeleteRequestExample demonstrates DELETE request
func DeleteRequestExample() {
	fmt.Println("\n--- DELETE Request ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"
	statusCode, err := DeleteResource(url)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Status Code: %d\n", statusCode)
}

// 8. Custom HTTP Client with Timeout

// HTTPClient represents a custom HTTP client
type HTTPClient struct {
	client      *http.Client
	baseURL     string
	defaultHeaders map[string]string
}

// NewHTTPClient creates a new HTTP client
func NewHTTPClient(timeout time.Duration) *HTTPClient {
	return &HTTPClient{
		client: &http.Client{
			Timeout: timeout,
		},
		defaultHeaders: make(map[string]string),
	}
}

// SetBaseURL sets the base URL for requests
func (c *HTTPClient) SetBaseURL(baseURL string) {
	c.baseURL = baseURL
}

// SetDefaultHeader sets a default header for all requests
func (c *HTTPClient) SetDefaultHeader(key, value string) {
	c.defaultHeaders[key] = value
}

// Get performs a GET request
func (c *HTTPClient) Get(path string) (string, error) {
	url := c.baseURL + path
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}

	// Add default headers
	for key, value := range c.defaultHeaders {
		req.Header.Set(key, value)
	}

	resp, err := c.client.Do(req)
	if err != nil {
		return "", fmt.Errorf("GET request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	if resp.StatusCode >= 400 {
		return "", fmt.Errorf("HTTP error: %d", resp.StatusCode)
	}

	return string(body), nil
}

// Post performs a POST request
func (c *HTTPClient) Post(path string, data map[string]interface{}) (string, error) {
	url := c.baseURL + path
	jsonData, err := json.Marshal(data)
	if err != nil {
		return "", err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}

	req.Header.Set("Content-Type", "application/json")

	// Add default headers
	for key, value := range c.defaultHeaders {
		if key != "Content-Type" {
			req.Header.Set(key, value)
		}
	}

	resp, err := c.client.Do(req)
	if err != nil {
		return "", fmt.Errorf("POST request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	if resp.StatusCode >= 400 {
		return "", fmt.Errorf("HTTP error: %d", resp.StatusCode)
	}

	return string(body), nil
}

// CustomClientExample demonstrates custom HTTP client
func CustomClientExample() {
	fmt.Println("\n--- Custom HTTP Client ---")

	client := NewHTTPClient(10 * time.Second)
	client.SetBaseURL("https://jsonplaceholder.typicode.com")
	client.SetDefaultHeader("User-Agent", "MyGoApp/1.0")

	// GET request
	body, err := client.Get("/posts/1")
	if err != nil {
		fmt.Printf("GET Error: %v\n", err)
		return
	}
	fmt.Printf("GET Response: %s\n", body)

	// POST request
	data := map[string]interface{}{
		"title":  "New Post",
		"body":   "Post content",
		"userId": 1,
	}

	body, err = client.Post("/posts", data)
	if err != nil {
		fmt.Printf("POST Error: %v\n", err)
		return
	}
	fmt.Printf("POST Response: %s\n", body)
}

// 9. Handling Response Headers

// GetWithResponseHeaders performs GET and returns headers
func GetWithResponseHeaders(url string) (string, http.Header, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", nil, err
	}

	return string(body), resp.Header, nil
}

// ResponseHeadersExample demonstrates reading response headers
func ResponseHeadersExample() {
	fmt.Println("\n--- Response Headers ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"
	body, headers, err := GetWithResponseHeaders(url)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("Response Headers:")
	for key, values := range headers {
		for _, value := range values {
			fmt.Printf("  %s: %s\n", key, value)
		}
	}

	fmt.Printf("\nBody: %s\n", body)
}

// 10. Request with Context (Timeout)

// GetWithContext performs GET with context timeout
func GetWithContext(url string, timeout time.Duration) (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return "", err
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("request failed: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response: %v", err)
	}

	return string(body), nil
}

// ContextExample demonstrates context with timeout
func ContextExample() {
	fmt.Println("\n--- Request with Context Timeout ---")

	url := "https://jsonplaceholder.typicode.com/posts/1"

	body, err := GetWithContext(url, 5*time.Second)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Response: %s\n", body)
}

// Main function
func main() {
	fmt.Println("=== Web Go HTTP Requests Examples ===\n")

	SimpleGetExample()
	GetWithHeadersExample()
	GetWithQueryParamsExample()
	PostJSONExample()
	PostFormExample()
	PutJSONExample()
	DeleteRequestExample()
	CustomClientExample()
	ResponseHeadersExample()
	ContextExample()

	fmt.Println("\n=== All HTTP Request Examples Completed ===")
}

💻 Serveur HTTP go

🟡 intermediate ⭐⭐⭐

Créer des serveurs HTTP simples avec routage, gestionnaires et middleware

⏱️ 25 min 🏷️ go, web, networking
Prerequisites: Intermediate Go, net/http package
// Web Go HTTP Server Examples
// Creating HTTP servers with routing and handlers

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"time"
)

// 1. Basic HTTP Server

// BasicHTTPServer demonstrates a simple HTTP server
func BasicHTTPServerExample() {
	fmt.Println("--- Basic HTTP Server ---")

	// Define handler
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!\n")
		fmt.Fprintf(w, "Path: %s\n", r.URL.Path)
		fmt.Fprintf(w, "Method: %s\n", r.Method)
	})

	http.HandleFunc("/about", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "About Page\n")
	})

	http.HandleFunc("/contact", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Contact Page\n")
	})

	fmt.Println("Server starting on http://localhost:8080")
	// In real usage: log.Fatal(http.ListenAndServe(":8080", nil))
	fmt.Println("(Server would run here)")
}

// 2. Server with Custom ServeMux

// CustomServeMuxExample demonstrates using custom ServeMux
func CustomServeMuxExample() {
	fmt.Println("\n--- Custom ServeMux ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Home Page\n")
	})

	mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "API Endpoint\n")
	})

	mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(map[string]string{"status": "healthy"})
	})

	server := &http.Server{
		Addr:    ":8080",
		Handler: mux,
	}

	fmt.Println("Server configured on :8080")
	// In real usage: log.Fatal(server.ListenAndServe())
	fmt.Println("(Server would run here)")
}

// 3. RESTful API Server

// Post represents a blog post
type Post struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Body   string `json:"body"`
	UserID int    `json:"userId"`
}

var posts = []Post{
	{ID: 1, Title: "First Post", Body: "Content 1", UserID: 1},
	{ID: 2, Title: "Second Post", Body: "Content 2", UserID: 1},
}

// RestfulAPIServer demonstrates RESTful API server
func RestfulAPIServerExample() {
	fmt.Println("\n--- RESTful API Server ---")

	mux := http.NewServeMux()

	// GET /posts - get all posts
	mux.HandleFunc("/posts", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodGet {
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(posts)
		} else {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})

	// GET /posts/{id} - get single post
	mux.HandleFunc("/posts/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodGet {
			// Extract ID from URL path
			idStr := strings.TrimPrefix(r.URL.Path, "/posts/")
			var id int
			fmt.Sscanf(idStr, "%d", &id)

			for _, post := range posts {
				if post.ID == id {
					w.Header().Set("Content-Type", "application/json")
					json.NewEncoder(w).Encode(post)
					return
				}
			}

			http.Error(w, "Post not found", http.StatusNotFound)
		} else {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})

	// POST /posts - create new post
	mux.HandleFunc("/posts/create", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodPost {
			var newPost Post
			err := json.NewDecoder(r.Body).Decode(&newPost)
			if err != nil {
				http.Error(w, "Invalid request body", http.StatusBadRequest)
				return
			}

			newPost.ID = len(posts) + 1
			posts = append(posts, newPost)

			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(http.StatusCreated)
			json.NewEncoder(w).Encode(newPost)
		} else {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})

	fmt.Println("RESTful API Server configured")
	// In real usage: log.Fatal(http.ListenAndServe(":8080", mux))
	fmt.Println("(Server would run here)")
}

// 4. Server with Middleware

// LoggerMiddleware logs all requests
func LoggerMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		fmt.Printf("[%s] %s %s\n", start.Format("2006-01-02 15:04:05"), r.Method, r.URL.Path)

		// Call next handler
		next.ServeHTTP(w, r)

		fmt.Printf("Completed in %v\n", time.Since(start))
	})
}

// CORSMiddleware adds CORS headers
func CORSMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusOK)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// AuthMiddleware validates authentication
func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")

		if token == "" {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		if token != "Bearer valid-token" {
			http.Error(w, "Forbidden", http.StatusForbidden)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// MiddlewareServerExample demonstrates server with middleware
func MiddlewareServerExample() {
	fmt.Println("\n--- Server with Middleware ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Public endpoint\n")
	})

	mux.HandleFunc("/protected", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Protected endpoint\n")
	})

	// Wrap middleware
	handler := CORSMiddleware(LoggerMiddleware(mux))

	server := &http.Server{
		Addr:    ":8080",
		Handler: handler,
	}

	fmt.Println("Server with middleware configured")
	// In real usage: log.Fatal(server.ListenAndServe())
	fmt.Println("(Server would run here)")
}

// 5. Server with Query Parameters

// QueryParamsServer demonstrates handling query parameters
func QueryParamsServerExample() {
	fmt.Println("\n--- Server with Query Parameters ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/search", func(w http.ResponseWriter, r *http.Request) {
		query := r.URL.Query()
		keyword := query.Get("q")
		page := query.Get("page")
		limit := query.Get("limit")

		result := map[string]interface{}{
			"keyword": keyword,
			"page":    page,
			"limit":   limit,
			"results": []string{"Result 1", "Result 2", "Result 3"},
		}

		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(result)
	})

	fmt.Println("Server with query parameters configured")
}

// 6. Static File Server

// StaticFileServerExample demonstrates serving static files
func StaticFileServerExample() {
	fmt.Println("\n--- Static File Server ---")

	mux := http.NewServeMux()

	// Serve static files from ./static directory
	fs := http.FileServer(http.Dir("./static"))
	mux.Handle("/static/", http.StripPrefix("/static/", fs))

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Welcome! Static files at /static/\n")
	})

	fmt.Println("Static file server configured")
	// In real usage: log.Fatal(http.ListenAndServe(":8080", mux))
}

// 7. Server with Graceful Shutdown

// GracefulShutdownExample demonstrates graceful shutdown
func GracefulShutdownExample() {
	fmt.Println("\n--- Graceful Shutdown ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Server running\n")
	})

	server := &http.Server{
		Addr:    ":8080",
		Handler: mux,
	}

	// Start server in goroutine
	go func() {
		fmt.Println("Server starting...")
		// In real usage: if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		// 	log.Fatal(err)
		// }
	}()

	// Simulate graceful shutdown
	time.Sleep(1 * time.Second)

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	fmt.Println("Shutting down server...")
	// In real usage: if err := server.Shutdown(ctx); err != nil {
	// 	log.Printf("Server shutdown error: %v", err)
	// }

	fmt.Println("Server gracefully stopped")
}

// 8. JSON Request/Response Handler

// User represents a user
type User struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

// JSONHandlerExample demonstrates JSON handling
func JSONHandlerExample() {
	fmt.Println("\n--- JSON Request/Response Handler ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/api/user", func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodPost:
			var user User
			err := json.NewDecoder(r.Body).Decode(&user)
			if err != nil {
				http.Error(w, "Invalid JSON", http.StatusBadRequest)
				return
			}

			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(http.StatusCreated)
			json.NewEncoder(w).Encode(map[string]interface{}{
				"message": "User created",
				"user":    user,
			})

		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})

	fmt.Println("JSON handler configured")
}

// 9. File Upload Handler

// FileUploadExample demonstrates file upload handling
func FileUploadExample() {
	fmt.Println("\n--- File Upload Handler ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		// Parse multipart form (max 10MB)
		err := r.ParseMultipartForm(10 << 20)
		if err != nil {
			http.Error(w, "Unable to parse form", http.StatusBadRequest)
			return
		}

		// Get file from form
		file, handler, err := r.FormFile("file")
		if err != nil {
			http.Error(w, "Error retrieving file", http.StatusBadRequest)
			return
		}
		defer file.Close()

		fmt.Printf("Uploaded file: %s (%d bytes)\n", handler.Filename, handler.Size)

		// Read file content
		fileBytes, err := ioutil.ReadAll(file)
		if err != nil {
			http.Error(w, "Error reading file", http.StatusInternalServerError)
			return
		}

		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, "File uploaded successfully: %s (%d bytes)\n", handler.Filename, len(fileBytes))
	})

	fmt.Println("File upload handler configured")
}

// 10. Server with TLS/HTTPS

// HTTPSServerExample demonstrates HTTPS server
func HTTPSServerExample() {
	fmt.Println("\n--- HTTPS Server ---")

	mux := http.NewServeMux()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Secure connection!\n")
	})

	// Server configuration
	server := &http.Server{
		Addr:    ":8443",
		Handler: mux,
	}

	fmt.Println("HTTPS server configured on :8443")
	// In real usage:
	// log.Fatal(server.ListenAndServeTLS("server.crt", "server.key"))
	fmt.Println("(HTTPS server would run here)")
}

// Main function
func main() {
	fmt.Println("=== Web Go HTTP Server Examples ===\n")

	BasicHTTPServerExample()
	CustomServeMuxExample()
	RestfulAPIServerExample()
	MiddlewareServerExample()
	QueryParamsServerExample()
	StaticFileServerExample()
	GracefulShutdownExample()
	JSONHandlerExample()
	FileUploadExample()
	HTTPSServerExample()

	fmt.Println("\n=== All HTTP Server Examples Completed ===")
}

💻 Sockets TCP go

🟡 intermediate ⭐⭐⭐

Établir des connexions TCP, envoyer/recevoir des données et construire une communication basée sur des sockets

⏱️ 25 min 🏷️ go, web, networking
Prerequisites: Intermediate Go, net package
// Web Go TCP Sockets Examples
// TCP socket programming for network communication

package main

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"strings"
	"time"
)

// 1. TCP Client

// TCPClient connects to a TCP server
func TCPClient(host string, port int) (net.Conn, error) {
	address := fmt.Sprintf("%s:%d", host, port)
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return nil, fmt.Errorf("failed to connect: %v", err)
	}

	fmt.Printf("Connected to %s\n", address)
	return conn, nil
}

// TCPClientExample demonstrates TCP client
func TCPClientExample() {
	fmt.Println("--- TCP Client ---")

	// Note: This example requires a running TCP server
	conn, err := TCPClient("localhost", 8080)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		fmt.Println("(Note: This requires a running TCP server)")
		return
	}
	defer conn.Close()

	// Send data
	message := "Hello, TCP Server!\n"
	_, err = conn.Write([]byte(message))
	if err != nil {
		fmt.Printf("Error writing: %v\n", err)
		return
	}

	fmt.Printf("Sent: %s", message)

	// Read response
	buffer := make([]byte, 1024)
	n, err := conn.Read(buffer)
	if err != nil {
		fmt.Printf("Error reading: %v\n", err)
		return
	}

	fmt.Printf("Received: %s\n", string(buffer[:n]))
}

// 2. TCP Server

// TCPServer starts a simple TCP server
func TCPServer(port int) error {
	address := fmt.Sprintf(":%d", port)
	listener, err := net.Listen("tcp", address)
	if err != nil {
		return fmt.Errorf("failed to listen: %v", err)
	}
	defer listener.Close()

	fmt.Printf("TCP Server listening on %s\n", address)

	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Printf("Error accepting connection: %v\n", err)
			continue
		}

		fmt.Printf("New connection from %s\n", conn.RemoteAddr())

		// Handle connection in goroutine
		go handleConnection(conn)
	}
}

// handleConnection handles a client connection
func handleConnection(conn net.Conn) {
	defer conn.Close()

	remoteAddr := conn.RemoteAddr().String()
	fmt.Printf("Handling connection from %s\n", remoteAddr)

	// Read data
	buffer := make([]byte, 1024)
	n, err := conn.Read(buffer)
	if err != nil {
		fmt.Printf("Error reading from %s: %v\n", remoteAddr, err)
		return
	}

	fmt.Printf("Received from %s: %s\n", remoteAddr, string(buffer[:n]))

	// Send response
	response := fmt.Sprintf("Echo: %s", string(buffer[:n]))
	_, err = conn.Write([]byte(response))
	if err != nil {
		fmt.Printf("Error writing to %s: %v\n", remoteAddr, err)
		return
	}

	fmt.Printf("Response sent to %s\n", remoteAddr)
}

// TCPServerExample demonstrates TCP server
func TCPServerExample() {
	fmt.Println("\n--- TCP Server ---")

	fmt.Println("Starting TCP server on :8080")
	fmt.Println("(In production, server.ListenAndServe() would block here)")

	// In real usage:
	// err := TCPServer(8080)
	// if err != nil {
	// 	log.Fatal(err)
	// }

	// For demonstration, just show the concept
	conn, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	defer conn.Close()

	fmt.Println("Server would accept connections here")
}

// 3. TCP Client with Timeout

// TCPClientWithTimeout connects with timeout
func TCPClientWithTimeout(host string, port int, timeout time.Duration) (net.Conn, error) {
	address := fmt.Sprintf("%s:%d", host, port)

	conn, err := net.DialTimeout("tcp", address, timeout)
	if err != nil {
		return nil, fmt.Errorf("connection timeout: %v", err)
	}

	fmt.Printf("Connected to %s (with timeout)\n", address)
	return conn, nil
}

// TimeoutClientExample demonstrates client with timeout
func TimeoutClientExample() {
	fmt.Println("\n--- TCP Client with Timeout ---")

	conn, err := TCPClientWithTimeout("localhost", 8080, 5*time.Second)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		fmt.Println("(Note: This requires a running TCP server)")
		return
	}
	defer conn.Close()

	fmt.Println("Connection established with timeout")
}

// 4. Bidirectional Communication

// ChatClient demonstrates bidirectional chat
func ChatClient(host string, port int) error {
	address := fmt.Sprintf("%s:%d", host, port)
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return err
	}
	defer conn.Close()

	fmt.Printf("Connected to chat server %s\n", address)

	// Start goroutine to read messages
	go func() {
		scanner := bufio.NewScanner(conn)
		for scanner.Scan() {
			fmt.Printf("Server: %s\n", scanner.Text())
		}
	}()

	// Read from stdin and send to server
	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		text := scanner.Text()
		if strings.ToLower(text) == "quit" {
			break
		}

		_, err := conn.Write([]byte(text + "\n"))
		if err != nil {
			return err
		}
	}

	return nil
}

// BidirectionalExample demonstrates bidirectional communication
func BidirectionalExample() {
	fmt.Println("\n--- Bidirectional Communication ---")

	fmt.Println("Chat client (requires running chat server)")
	fmt.Println("(In production, would run ChatClient here)")
}

// 5. UDP Client/Server

// UDPServer starts a UDP server
func UDPServer(port int) error {
	address := fmt.Sprintf(":%d", port)
	conn, err := net.ListenPacket("udp", address)
	if err != nil {
		return fmt.Errorf("failed to listen: %v", err)
	}
	defer conn.Close()

	fmt.Printf("UDP Server listening on %s\n", address)

	buffer := make([]byte, 1024)
	for {
		n, addr, err := conn.ReadFrom(buffer)
		if err != nil {
			fmt.Printf("Error reading: %v\n", err)
			continue
		}

		fmt.Printf("Received from %s: %s\n", addr, string(buffer[:n]))

		// Send response
		response := []byte("UDP Acknowledgment")
		_, err = conn.WriteTo(response, addr)
		if err != nil {
			fmt.Printf("Error writing: %v\n", err)
		}
	}
}

// UDPClient sends data to UDP server
func UDPClient(host string, port int, message string) error {
	address := fmt.Sprintf("%s:%d", host, port)
	conn, err := net.Dial("udp", address)
	if err != nil {
		return fmt.Errorf("failed to connect: %v", err)
	}
	defer conn.Close()

	fmt.Printf("Sending to %s: %s\n", address, message)

	_, err = conn.Write([]byte(message))
	if err != nil {
		return fmt.Errorf("error sending: %v", err)
	}

	// Read response
	buffer := make([]byte, 1024)
	n, err := conn.Read(buffer)
	if err != nil {
		return fmt.Errorf("error reading: %v", err)
	}

	fmt.Printf("Received: %s\n", string(buffer[:n]))
	return nil
}

// UDPExample demonstrates UDP communication
func UDPExample() {
	fmt.Println("\n--- UDP Client/Server ---")

	fmt.Println("UDP Server starting on :8081")
	fmt.Println("(In production, UDPServer would run here)")

	// Client example
	fmt.Println("\nUDP Client (requires running UDP server)")
	err := UDPClient("localhost", 8081, "Hello UDP!")
	if err != nil {
		fmt.Printf("Error: %v\n", err)
	}
}

// 6. Protocol Buffers over TCP

// SendBinaryMessage sends binary data with length prefix
func SendBinaryMessage(conn net.Conn, data []byte) error {
	// Send message length first (4 bytes)
	length := uint32(len(data))
	err := binary.Write(conn, binary.BigEndian, length)
	if err != nil {
		return fmt.Errorf("error writing length: %v", err)
	}

	// Send data
	_, err = conn.Write(data)
	if err != nil {
		return fmt.Errorf("error writing data: %v", err)
	}

	return nil
}

// ReceiveBinaryMessage receives binary data with length prefix
func ReceiveBinaryMessage(conn net.Conn) ([]byte, error) {
	// Read message length
	var length uint32
	err := binary.Read(conn, binary.BigEndian, &length)
	if err != nil {
		return nil, fmt.Errorf("error reading length: %v", err)
	}

	// Read data
	data := make([]byte, length)
	_, err = io.ReadFull(conn, data)
	if err != nil {
		return nil, fmt.Errorf("error reading data: %v", err)
	}

	return data, nil
}

// BinaryProtocolExample demonstrates binary protocol
func BinaryProtocolExample() {
	fmt.Println("\n--- Binary Protocol over TCP ---")

	fmt.Println("Binary protocol demonstration")
	fmt.Println("(Would use SendBinaryMessage and ReceiveBinaryMessage)")
}

// 7. Connection Pool

// ConnPool represents a connection pool
type ConnPool struct {
	conns chan net.Conn
	factory func() (net.Conn, error)
}

// NewConnPool creates a new connection pool
func NewConnPool(size int, factory func() (net.Conn, error)) (*ConnPool, error) {
	pool := &ConnPool{
		conns:   make(chan net.Conn, size),
		factory: factory,
	}

	// Initialize connections
	for i := 0; i < size; i++ {
		conn, err := factory()
		if err != nil {
			return nil, err
		}
		pool.conns <- conn
	}

	return pool, nil
}

// Get gets a connection from the pool
func (p *ConnPool) Get() (net.Conn, error) {
	select {
	case conn := <-p.conns:
		return conn, nil
	default:
		// Pool exhausted, create new connection
		return p.factory()
	}
}

// Put returns a connection to the pool
func (p *ConnPool) Put(conn net.Conn) {
	select {
	case p.conns <- conn:
		// Connection returned to pool
	default:
		// Pool full, close connection
		conn.Close()
	}
}

// Close closes all connections in the pool
func (p *ConnPool) Close() {
	close(p.conns)
	for conn := range p.conns {
		conn.Close()
	}
}

// ConnectionPoolExample demonstrates connection pooling
func ConnectionPoolExample() {
	fmt.Println("\n--- Connection Pool ---")

	// Create pool
	pool, err := NewConnPool(3, func() (net.Conn, error) {
		return net.Dial("tcp", "localhost:8080")
	})

	if err != nil {
		fmt.Printf("Error creating pool: %v\n", err)
		fmt.Println("(Note: This requires a running TCP server)")
		return
	}

	defer pool.Close()

	// Get connection
	conn, err := pool.Get()
	if err != nil {
		fmt.Printf("Error getting connection: %v\n", err)
		return
	}

	fmt.Printf("Got connection from pool: %v\n", conn.RemoteAddr())

	// Return connection
	pool.Put(conn)

	fmt.Println("Connection returned to pool")
}

// 8. Socket Options

// SetSocketOptions configures socket options
func SetSocketOptions(conn net.Conn) error {
	tcpConn, ok := conn.(*net.TCPConn)
	if !ok {
		return fmt.Errorf("not a TCP connection")
	}

	// Set keep-alive
	err := tcpConn.SetKeepAlive(true)
	if err != nil {
		return fmt.Errorf("error setting keep-alive: %v", err)
	}

	// Set keep-alive period
	err = tcpConn.SetKeepAlivePeriod(30 * time.Second)
	if err != nil {
		return fmt.Errorf("error setting keep-alive period: %v", err)
	}

	// Set no delay
	err = tcpConn.SetNoDelay(true)
	if err != nil {
		return fmt.Errorf("error setting no delay: %v", err)
	}

	return nil
}

// SocketOptionsExample demonstrates socket options
func SocketOptionsExample() {
	fmt.Println("\n--- Socket Options ---")

	fmt.Println("Socket options configured (keep-alive, no delay)")
	fmt.Println("(Would use SetSocketOptions on TCP connections)")
}

// Main function
func main() {
	fmt.Println("=== Web Go TCP Sockets Examples ===\n")

	TCPClientExample()
	TCPServerExample()
	TimeoutClientExample()
	BidirectionalExample()
	UDPExample()
	BinaryProtocolExample()
	ConnectionPoolExample()
	SocketOptionsExample()

	fmt.Println("\n=== All TCP Sockets Examples Completed ===")
}