Twirp RPC 기반 의 간단 한 JSON Api Gateway 구현

3372 단어
Twirp 는 Twichtv 가 2018 년 에 시작 한 아주 간단 한 RPC 프레임 워 크 로 당시 공식 소개 글 Twirp: a sweet new RPC framework for Go.기능 상 으로 는 명성 이 자자 한 grpc 보다 못 하지만 작고 유연 하 며 Go 원생 의  http.Handler, 기 존의 임 의  Router  중간 부품 과 배합 하여 사용 하기;protobuf 와 json 형식 전송 을 지원 하고 디 버 깅 이 편리 합 니 다.그리고 저 는 개인 적 으로 좋아해요.  Error  실현, 직관 적 이 고 확장 성 이 좋다.
Twirp 는 json 형식의 api 요청 을 지원 합 니 다. 전단 에 직접 접속 하여 사용 할 수 있 습 니 다.그러나 요청 은 모두 통 일 된 POST 요청 입 니 다. url 은 / twirp / package. name / method 라 는 형식 입 니 다.자기 회사 의 전단 을 설득 해 이런 접속 방식 을 받 아들 일 수 있다 고 해도 제3자 협력 업 체 에 공개 적 으로 사용 하기 어렵다.그래서 grpc gateway 와 같은 것 이 필요 합 니 다. restful 스타일 의 api 를 제공 할 수 있 습 니 다.또한 프로젝트 의 역사적 원인 으로 되 돌아 가 고 싶 은 데 이 터 는 다음 과 같은 형식 으로 되 돌아 갑 니 다.
// ok{
    "data": { // twirp         data     
        "foo":"bar"
    }}// error{
    "code": 10002, // twirp     error code   'permission_denied'    string
    "msg": "error msg"}

수요 가 명확 해 지면 남 은 실현 도 뚜렷 해진 다.우 리 는 비슷 한 것 이 필요 하 다. httputil.ReverseProxy 그래 요. 맞아요. 받았어요. request twirp 의 요구 에 따라 개조 한 후, 좋 은 twirp rpc 서 비 스 를 실현 하 는 데 맡 깁 니 다.body 처리 에 대해 사용자 정의 http.ResponsWriter 바디 를 조정 한 후 진정한 Writer 를 기록 합 니 다.다음은 go - chi / chi 를 Router 로 사용 하여 간단 한 twirp api gateway 의 예 를 들 겠 습 니 다.이 예 의 전체 코드 는 yiplee / twirp - gateway - example 에서 시 작 됩 니 다.
/reversetwirp.go
  • url path params 와 query params 를 body
  • 로 포장 합 니 다.
  • request method 를 POST
  • 로 수정
  • url path 를 대응 하 는 / twirp / package. name / method
  • 로 수정 합 니 다.
  • twirp rpc handler 에 전송 요청
  • 사용 예시 참조 /api/books
    /render/response.go 포장 응답
  • 차단 응답 상태
  • 성공 적 인 귀환 이 라면 body 를 data 로 포장 한 후 진정한 Response Writer
  • 에 기록 합 니 다.
  • 실패 한 귀환 이 라면 Twirp Error 를 복원 하고 새 것 을 만 듭 니 다. errorResponse Response Writer 쓰기
  • Server
    Server 는 rpc 와 rest api 의 Handler 를 실현 했다.
    Route RPC
    path 접두사 가 일치 하 는 방식 으로 rpc 요청 경 로 를 대응 하 는 실현 으로 이동 합 니 다.
    func (s Server) HandleRpc() http.Handler {
        r := chi.NewRouter()
        r.Use(resetRoutePath)
    
        // book service
        {
            svc := book.New(s.Books)
            r.Mount(svc.PathPrefix(), svc)
        }
    
        return r
    }
    

    Route Rest Api
    restful 스타일 의 api 요청 을 제공 합 니 다. ReverseTwirp 에서 이 루어 집 니 다.
    func (s Server) HandleApi() http.Handler {
        r := chi.NewRouter()
        r.Use(render.WrapResponse(true))
    
        r.Route("/books", func(r chi.Router) {
            svc := book.New(s.Books)
            rt := reversetwirp.NewSingleTwirpServerProxy(svc)
    
            r.Post("/", rt.Handle("Create", nil))
            r.Get("/{id}", rt.Handle("Find", nil))
        })
    
        return r
    }
    

    서버 시작
    r := chi.NewMux()
    r.Use(middleware.Recoverer)
    r.Use(middleware.Logger)
    
    books := book.New()
    svr := handler.New(books)
    
    r.Mount("/twirp", svr.HandleRpc())
    r.Mount("/api", svr.HandleApi())
    r.Mount("/hc", hc.Handler())
    
    addr := fmt.Sprintf(":%d", cfg.port)
    if err := http.ListenAndServe(addr, r); err != nil {
        log.Fatal(err)
    }
    

    마지막 으로 우 리 는 이미 이 유 를 제공 했다. twirp code generator 생 성 rpc 클 라 이언 트 코드 내부 서비스 에 직접 사용 할 수 있 고 제공 되 었 다.
    GET /api/books/:id
    
    POST /api/books
    

    이 두 개의 rest api 는 전단 에서 사용 할 수 있 습 니 다.
    전체 코드 는 yiplee / twirp - gateway - example 를 보십시오.

    좋은 웹페이지 즐겨찾기