v2.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package v2
  2. import (
  3. "context"
  4. "fmt"
  5. grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
  6. "github.com/improbable-eng/grpc-web/go/grpcweb"
  7. "github.com/labstack/echo/v4"
  8. "google.golang.org/grpc"
  9. "google.golang.org/grpc/credentials/insecure"
  10. "google.golang.org/grpc/reflection"
  11. apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
  12. "github.com/usememos/memos/server/profile"
  13. "github.com/usememos/memos/store"
  14. )
  15. type APIV2Service struct {
  16. Secret string
  17. Profile *profile.Profile
  18. Store *store.Store
  19. grpcServer *grpc.Server
  20. grpcServerPort int
  21. }
  22. func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store, grpcServerPort int) *APIV2Service {
  23. grpc.EnableTracing = true
  24. authProvider := NewGRPCAuthInterceptor(store, secret)
  25. grpcServer := grpc.NewServer(
  26. grpc.ChainUnaryInterceptor(
  27. authProvider.AuthenticationInterceptor,
  28. ),
  29. )
  30. apiv2pb.RegisterSystemServiceServer(grpcServer, NewSystemService(profile, store))
  31. apiv2pb.RegisterUserServiceServer(grpcServer, NewUserService(store, secret))
  32. apiv2pb.RegisterMemoServiceServer(grpcServer, NewMemoService(store))
  33. apiv2pb.RegisterTagServiceServer(grpcServer, NewTagService(store))
  34. apiv2pb.RegisterResourceServiceServer(grpcServer, NewResourceService(store))
  35. reflection.Register(grpcServer)
  36. return &APIV2Service{
  37. Secret: secret,
  38. Profile: profile,
  39. Store: store,
  40. grpcServer: grpcServer,
  41. grpcServerPort: grpcServerPort,
  42. }
  43. }
  44. func (s *APIV2Service) GetGRPCServer() *grpc.Server {
  45. return s.grpcServer
  46. }
  47. // RegisterGateway registers the gRPC-Gateway with the given Echo instance.
  48. func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error {
  49. // Create a client connection to the gRPC Server we just started.
  50. // This is where the gRPC-Gateway proxies the requests.
  51. conn, err := grpc.DialContext(
  52. ctx,
  53. fmt.Sprintf(":%d", s.grpcServerPort),
  54. grpc.WithTransportCredentials(insecure.NewCredentials()),
  55. )
  56. if err != nil {
  57. return err
  58. }
  59. gwMux := grpcRuntime.NewServeMux()
  60. if err := apiv2pb.RegisterSystemServiceHandler(context.Background(), gwMux, conn); err != nil {
  61. return err
  62. }
  63. if err := apiv2pb.RegisterUserServiceHandler(context.Background(), gwMux, conn); err != nil {
  64. return err
  65. }
  66. if err := apiv2pb.RegisterMemoServiceHandler(context.Background(), gwMux, conn); err != nil {
  67. return err
  68. }
  69. if err := apiv2pb.RegisterTagServiceHandler(context.Background(), gwMux, conn); err != nil {
  70. return err
  71. }
  72. if err := apiv2pb.RegisterResourceServiceHandler(context.Background(), gwMux, conn); err != nil {
  73. return err
  74. }
  75. e.Any("/api/v2/*", echo.WrapHandler(gwMux))
  76. // GRPC web proxy.
  77. options := []grpcweb.Option{
  78. grpcweb.WithCorsForRegisteredEndpointsOnly(false),
  79. grpcweb.WithOriginFunc(func(origin string) bool {
  80. return true
  81. }),
  82. }
  83. wrappedGrpc := grpcweb.WrapServer(s.grpcServer, options...)
  84. e.Any("/memos.api.v2.*", echo.WrapHandler(wrappedGrpc))
  85. return nil
  86. }