>백엔드 개발 >Golang >Golang에서 간단한 API 게이트웨이를 구현하는 방법

Golang에서 간단한 API 게이트웨이를 구현하는 방법

藏色散人
藏色散人앞으로
2020-08-31 17:06:313769검색

다음 칼럼에서는 Golangtutorial 칼럼에서 Golang으로 간단한 API 게이트웨이를 구현하는 방법을 소개하겠습니다. 필요한 친구들에게 도움이 되길 바랍니다!

Golang에서 간단한 API 게이트웨이를 구현하는 방법

최근 프로젝트에서는 백엔드 개발에 마이크로서비스 아키텍처인 go-kit을 사용했습니다. 마이크로서비스 아키텍처 스타일에서는 대규모 애플리케이션이 여러 개의 소규모 서비스 시스템으로 분할됩니다. 이러한 소규모 시스템은 자체 시스템을 구성할 수 있습니다. 이는 이러한 소규모 시스템이 자체 데이터베이스, 프레임워크, 심지어 언어까지 가질 수 있음을 의미합니다. 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
// 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}}

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)}

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

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

代码

实例代码只涉及微服务中 userauthAPI 게이트웨이(API Gataway)

실제로 인터넷에는 기성 구현 프레임워크가 많이 있지만 이 프로젝트의 요구 사항은 비교적 간단하므로 Golang을 사용하여 구현하겠습니다. 우리 스스로.

구현

API 게이트웨이는 서버이자 시스템에 대한 유일한 입구입니다. 객체지향 디자인 관점에서는 파사드 패턴과 유사합니다. API 게이트웨이는 시스템의 내부 아키텍처를 캡슐화하고 각 클라이언트에 대해 맞춤형 API를 제공합니다. 또한 인증, 모니터링, 로드 밸런싱, 캐싱, 요청 샤딩 및 관리, 정적 응답 처리와 같은 다른 책임도 가질 수 있습니다. 🎜🎜🎜API 게이트웨이를 구현하는 데 사용되는 많은 기술이 있으며 대략 다음 범주로 나뉩니다. 🎜
  • 일반 역방향 프록시: Nginx, Haproxy , ...
  • 네트워크 프로그래밍 프레임워크: Netty, Servlet, ...
  • API 게이트웨이 프레임워크: Spring Cloud Gateway , Zuul, Zuul2,...
🎜API 게이트웨이의 가장 기본적인 기능은 역방향 프록시입니다. 이를 구현하는 방법은 다양합니다. 이 기사에서는 표준 라이브러리 net/http/httputil 패키지의 ReverseProxy 유형을 기반으로 간단한 역방향 프록시를 구현합니다. 역방향 프록시 구현에는 주로 func NewSingleHostReverseProxy(target *url.URL) *ReverseProxytype 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()}
rrreee🎜NewSingleHostReverseProxyURL 요청을 지정된 의 <code>target 체계ReverseProxy를 반환합니다. /code>, 호스트, 기본 경로. 🎜rrreee🎜ReverseProxy 유형에는 DirectorModifyResponse라는 두 가지 중요한 속성이 있습니다. 두 속성 모두 클라이언트가 수신할 때 함수 유형입니다. 요청이 있으면 ServeHTTP 함수는 먼저 Director 함수를 호출하여 요청의 대상 주소, 요청 헤더 등을 수정하는 등 수신된 요청 본문을 수정합니다. 수정된 요청을 사용합니다. 본문은 응답을 받은 후 ModifyResponse 함수를 호출하여 응답을 수정합니다. 마지막으로 수정된 응답 본문이 복사되어 클라이언트에 응답됩니다. 전체 역방향 프록시 프로세스. 🎜🎜NewSingleHostReverseProxy에서 소스 코드는 수신 URL을 구문 분석하고 Director 수정을 완료했습니다. NewSingleHostReverseProxy만 호출하면 됩니다. 함수에 대상 서버의 URL을 전달하면 간단한 역방향 프록시가 완성됩니다. 🎜

코드

🎜예제 코드에는 마이크로서비스의 userauth 모듈만 포함됩니다. 실제에 따라 일부를 수정할 수 있습니다. 필요🎜🎜rrreee🎜

위 내용은 Golang에서 간단한 API 게이트웨이를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제