Heim > Backend-Entwicklung > Golang > So implementieren Sie ein einfaches API-Gateway in Golang

So implementieren Sie ein einfaches API-Gateway in Golang

藏色散人
Freigeben: 2020-08-31 17:07:02
nach vorne
3736 Leute haben es durchsucht

In der folgenden Kolumne erfahren Sie, wie Sie ein einfaches API-Gateway in Golang aus der Kolumne GolangTutorial implementieren. Ich hoffe, dass es für Freunde hilfreich ist, die es brauchen!

So implementieren Sie ein einfaches API-Gateway in Golang

In einem aktuellen Projekt wurde das Microservice-Architektur-go-kit für die Backend-Entwicklung verwendet. Im Microservice-Architekturstil wird eine große Anwendung in mehrere kleine Servicesysteme aufgeteilt, was bedeutet, dass diese kleinen Systeme ihre eigenen Datenbanken, Frameworks und sogar Sprachen haben können go-kit进行后端的开发。在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,因此我们需要设计一个API 网关(API Gataway),其实网上已经有较多现成的实现框架,但是本项目的需求是比较简单的,因此将使用Golang自行实现。

实现

API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。

用于实现API网关的技术有很多,大致分为这么几类:

  • 通用反向代理:NginxHaproxy、……
  • 网络编程框架:NettyServlet、……
  • API网关框架:Spring Cloud GatewayZuulZuul2、……

API网关最基本的功能就是反向代理。其实现方式有很多,本文将基于标准库net/http/httputil包中的ReverseProxy类型来实现实现一个简单的反向代理。反向代理的实现主要涉及到func NewSingleHostReverseProxy(target *url.URL) *ReverseProxytype ReverseProxy

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
Nach dem Login kopieren
// NewSingleHostReverseProxy returns a new ReverseProxy that routes// URLs to the scheme, host, and base path provided in target. If the// target's path is "/base" and the incoming request was for "/dir",// the target request will be for /base/dir.// NewSingleHostReverseProxy does not rewrite the Host header.// To rewrite Host headers, use ReverseProxy directly with a custom// Director policy.func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
	targetQuery := target.RawQuery
	director := func(req *http.Request) {
		req.URL.Scheme = target.Scheme
		req.URL.Host = target.Host
		req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
		if targetQuery == "" || req.URL.RawQuery == "" {
			req.URL.RawQuery = targetQuery + req.URL.RawQuery		} else {
			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery		}
		if _, ok := req.Header["User-Agent"]; !ok {
			// explicitly disable User-Agent so it's not set to default value
			req.Header.Set("User-Agent", "")
		}
	}
	return &ReverseProxy{Director: director}}
Nach dem Login kopieren

NewSingleHostReverseProxy返回一个新的ReverseProxy,将URLs请求路由到targe的指定的scheme, host, base path

// ReverseProxy is an HTTP Handler that takes an incoming request and// sends it to another server, proxying the response back to the// client.type ReverseProxy struct {
	// Director must be a function which modifies
	// the request into a new request to be sent
	// using Transport. Its response is then copied
	// back to the original client unmodified.
	// Director must not access the provided Request
	// after returning.
	Director func(*http.Request)

	Transport http.RoundTripper

	FlushInterval time.Duration

	ErrorLog *log.Logger

	BufferPool BufferPool	// ModifyResponse is an optional function that modifies the
	// Response from the backend. It is called if the backend
	// returns a response at all, with any HTTP status code.
	// If the backend is unreachable, the optional ErrorHandler is
	// called without any call to ModifyResponse.
	//
	// If ModifyResponse returns an error, ErrorHandler is called
	// with its error value. If ErrorHandler is nil, its default
	// implementation is used.
	ModifyResponse func(*http.Response) error

	ErrorHandler func(http.ResponseWriter, *http.Request, error)}
Nach dem Login kopieren

ReverseProxy类型有两个重要的属性,分别是DirectorModifyResponse,这两个属性都是函数类型,在接收到客户端请求时,ServeHTTP函数首先调用Director函数对接受到的请求体进行修改,例如修改请求的目标地址、请求头等;然后使用修改后的请求体发起新的请求,接收到响应后,调用ModifyResponse函数对响应进行修改,最后将修改后的响应体拷贝并响应给客户端,这样就实现了反向代理的整个流程。

NewSingleHostReverseProxy中源码已经对传入的URLs进行解析并且完成了Director的修改,我们只需要调用NewSingleHostReverseProxy函数并且传入目标服务器的URL即可,一个简单的反向代理就完成了啦。

代码

实例代码只涉及微服务中 userauthAPI Gateway (API Gataway)

Tatsächlich gibt es im Internet viele vorgefertigte Implementierungsframeworks, aber die Anforderungen dieses Projekts sind relativ einfach, daher verwenden wir Golang, um es zu implementieren uns.

Implementierung

Das API-Gateway ist ein Server und der einzige Zugang zum System. Aus objektorientierter Gestaltungsperspektive ähnelt es dem Fassadenmuster. Das API-Gateway kapselt die interne Architektur des Systems und stellt für jeden Client eine angepasste API bereit. Es kann auch andere Aufgaben wie Authentifizierung, Überwachung, Lastausgleich, Caching, Anforderungs-Sharding und -Verwaltung sowie statische Antwortverarbeitung übernehmen. 🎜🎜🎜Es gibt viele Technologien, die zur Implementierung von API-Gateways verwendet werden, die grob in die folgenden Kategorien unterteilt werden: 🎜
  • Allgemeiner Reverse-Proxy: Nginx, Haproxy , ...
  • Netzwerkprogrammier-Framework: Netty, Servlet, ...
  • API-Gateway-Framework: Spring Cloud Gateway , Zuul, Zuul2,...
🎜Die grundlegendste Funktion des API-Gateways ist der Reverse-Proxy. Es gibt viele Möglichkeiten, es zu implementieren. In diesem Artikel wird ein einfacher Reverse-Proxy basierend auf dem Typ ReverseProxy im Paket der Standardbibliothek net/http/httputil implementiert. Die Implementierung des Reverse-Proxy umfasst hauptsächlich func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy und type ReverseProxy. 🎜
package mainimport (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings")type handle struct {
	host string
	port string}type Service struct {
	auth *handle
	user *handle}func (this *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var remote *url.URL	if strings.Contains(r.RequestURI, "api/auth") {
		remote, _ = url.Parse("http://" + this.auth.host + ":" + this.auth.port)
	} else if strings.Contains(r.RequestURI, "api/user") {
		remote, _ = url.Parse("http://" + this.user.host + ":" + this.user.port)
	} else {
		fmt.Fprintf(w, "404 Not Found")
		return
	}
	proxy := httputil.NewSingleHostReverseProxy(remote)
	proxy.ServeHTTP(w, r)}func startServer() {
	// 注册被代理的服务器 (host, port)
	service := &Service{
		auth: &handle{host: "127.0.0.1", port: "8081"},
		user: &handle{host: "127.0.0.1", port: "8082"},
	}
	err := http.ListenAndServe(":8888", service)
	if err != nil {
		log.Fatalln("ListenAndServe: ", err)
	}}func main() {
	startServer()}
Nach dem Login kopieren
rrreee🎜NewSingleHostReverseProxy gibt einen neuen ReverseProxy zurück, der URLs-Anfragen an den angegebenen des <code>target-Schemas, host, base path. 🎜rrreee🎜Der Typ ReverseProxy hat zwei wichtige Attribute, nämlich Director und ModifyResponse. Beim Empfang handelt es sich um einen Bei einer Anfrage ruft die Funktion ServeHTTP zunächst die Funktion Director auf, um den empfangenen Anforderungstext zu ändern, z. B. die Zieladresse der Anforderung, den Anforderungsheader usw. und dann verwendet den geänderten Anforderungstext. Nach Erhalt der Antwort wird die Funktion ModifyResponse aufgerufen, um die Antwort zu ändern. Anschließend wird der geänderte Antworttext kopiert und dem Client geantwortet gesamten Reverse-Proxy-Prozess. 🎜🎜In NewSingleHostReverseProxy hat der Quellcode die eingehenden URLs analysiert und die Änderung von Director abgeschlossen. Wir müssen nur NewSingleHostReverseProxy aufrufen -Funktion verwenden und die URL des Zielservers übergeben, ist ein einfacher Reverse-Proxy abgeschlossen. 🎜

Code

🎜Der Beispielcode betrifft nur die Module user und auth im Microservice. Sie können einige davon entsprechend den tatsächlichen Anforderungen ändern Bedürfnisse🎜🎜rrreee🎜

Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein einfaches API-Gateway in Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage