gRPC: 如何实现文件上传 Restful API ?

2021-12-13 00:16:35 浏览数 (1)

介绍

本文将介绍如何在 gRPC 微服务中实现文件上传 Restful API?

为什么需要这么一篇文章?

gRPC 里我们可以通过 Streaming 来互传大文件,不过通过 grpc-gateway on gRPC 我们是无法实现的。 因此,需要绕过 gRPC 直接在 grpc-gateway 中添加 API。

我们将会使用 rk-boot 来启动 gRPC 服务。

请访问如下地址获取完整教程:https://rkdev.info/cn https://rkdocs.netlify.app/cn (备用)

安装

代码语言:txt复制
go get github.com/rookie-ninja/rk-boot
go get github.com/rookie-ninja/rk-grpc

快速开始

rk-boot 默认集成了 grpc-gateway,并且会默认启动。

1.创建 boot.yaml

代码语言:txt复制
---
grpc:
  - name: greeter                   # Name of grpc entry
    port: 8080                      # Port of grpc entry
    enabled: true                   # Enable grpc entry

2.创建 main.go

注意,grpcEntry.GwMux.HandlePath() 一定要写到 boot.Bootstrap() 之后,否则会出现 Panic。

代码语言:txt复制
package main

import (
	"context"
	"fmt"
	"github.com/rookie-ninja/rk-boot"
	"github.com/rookie-ninja/rk-grpc/boot"
	"net/http"
)

// Application entrance.
func main() {
	// Create a new boot instance.
	boot := rkboot.NewBoot()

	// Bootstrap
	boot.Bootstrap(context.Background())

	// Get grpc entry with name
	grpcEntry := boot.GetEntry("greeter").(*rkgrpc.GrpcEntry)

	// Attachment upload from http/s handled manually
	grpcEntry.GwMux.HandlePath("POST", "/v1/files", handleBinaryFileUpload)

	// Wait for shutdown sig
	boot.WaitForShutdownSig(context.Background())
}

func handleBinaryFileUpload(w http.ResponseWriter, req *http.Request, params map[string]string) {
	err := req.ParseForm()
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to parse form: %s", err.Error()), http.StatusBadRequest)
		return
	}

	f, header, err := req.FormFile("attachment")
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to get file 'attachment': %s", err.Error()), http.StatusBadRequest)
		return
	}
	defer f.Close()

	fmt.Println(header)

	//
	// Now do something with the io.Reader in `f`, i.e. read it into a buffer or stream it to a gRPC client side stream.
	// Also `header` will contain the filename, size etc of the original file.
	//
}

3.验证

代码语言:txt复制
$ curl -X POST -F "attachment=@xxx.txt" localhost:8080/v1/files

0 人点赞