
Замісник на Go
Замісник — це об’єкт, який виступає прошарком між клієнтом та реальним сервісним об’єктом. Замісник отримує виклики від клієнта, виконує свою функцію (контроль доступу, кешування, зміна запиту та інше), а потім передає виклик сервісному об’єктові.
Замісник має той самий інтерфейс, що і реальний об’єкт, тому для клієнта немає різниці — працювати з реальним об’єктом безпосередньо, чи за допомогою замісника.
Концептуальний приклад
Такий веб-сервер, як Nginx, може виконувати функції Замісника (проксі) для сервера вашого додатку:
- Він надає контрольований доступ до сервера вашого додатку.
- Він може забезпечити обмеження трафіку.
- Він може виконувати кешування запитів.
server.go: Інтерфейс сервісу
package main type server interface { handleRequest(string, string) (int, string) }
nginx.go: Замісник
package main type Nginx struct { application *Application maxAllowedRequest int rateLimiter map[string]int } func newNginxServer() *Nginx { return &Nginx{ application: &Application{}, maxAllowedRequest: 2, rateLimiter: make(map[string]int), } } func (n *Nginx) handleRequest(url, method string) (int, string) { allowed := n.checkRateLimiting(url) if !allowed { return 403, "Not Allowed" } return n.application.handleRequest(url, method) } func (n *Nginx) checkRateLimiting(url string) bool { if n.rateLimiter[url] == 0 { n.rateLimiter[url] = 1 } if n.rateLimiter[url] > n.maxAllowedRequest { return false } n.rateLimiter[url] = n.rateLimiter[url] + 1 return true }
application.go: Реальний сервіс
package main type Application struct { } func (a *Application) handleRequest(url, method string) (int, string) { if url == "/app/status" && method == "GET" { return 200, "Ok" } if url == "/create/user" && method == "POST" { return 201, "User Created" } return 404, "Not Ok" }
main.go: Клієнтський код
package main import "fmt" func main() { nginxServer := newNginxServer() appStatusURL := "/app/status" createuserURL := "/create/user" httpCode, body := nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(createuserURL, "POST") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(createuserURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) }
output.txt: Результат виконання
Url: /app/status HttpCode: 200 Body: Ok Url: /app/status HttpCode: 200 Body: Ok Url: /app/status HttpCode: 403 Body: Not Allowed Url: /app/status HttpCode: 201 Body: User Created Url: /app/status HttpCode: 404 Body: Not Ok
На основі: Golang By Example