diff --git a/.env b/.env index c1c9397..bbfa027 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ DB_DRIVER=postgres DB_SOURCE=postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable -MIGRATION_URL=file://db/migration +MIGRATION_URL=file://migration HTTP_SERVER_ADDRESS=0.0.0.0:8080 GRPC_SERVER_ADDRESS=0.0.0.0:50051 TOKEN_SYMMETRIC_KEY=12345678901234567890123456789012 diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index 0e0a403..9ecab7b 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -1,10 +1,10 @@ - - - - - + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6e911f1..adf8de8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /app COPY --from=builder /app/main . COPY .env . COPY start.sh . -COPY db/migration ./db/migration +COPY migration ./db/migration EXPOSE 8080 ENTRYPOINT [ "/app/start.sh" ] \ No newline at end of file diff --git a/Makefile b/Makefile index ac5a270..d2a3ef4 100644 --- a/Makefile +++ b/Makefile @@ -8,16 +8,16 @@ dropdb: docker exec -it postgres16 dropdb simple_bank migrate-up: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up + migrate -path migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up migrate-down: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down + migrate -path migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down migrate-up1: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up 1 + migrate -path migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up 1 migrate-down1: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down 1 + migrate -path migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down 1 sqlc: sqlc generate @@ -26,22 +26,22 @@ test: go test -v -cover ./... server: - go run main.go + go run cmd/main.go dbdocs: - dbdocs build doc/database.dbml + dbdocs build docs/database.dbml mock: - mockgen -package mockdb -destination db/mock/store.go github.com/cukhoaimon/SimpleBank/db/sqlc Store + mockgen -package mockdb -destination internal/delivery/http/mock/store.go github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc Store proto: - del doc\swagger\*.swagger.json & - del pb\*.pb.go & - protoc --proto_path=proto --go_out=pb --go_opt paths=source_relative \ - --go-grpc_out=pb --go-grpc_opt paths=source_relative \ - --grpc-gateway_out=pb --grpc-gateway_opt paths=source_relative \ - --openapiv2_out=doc/swagger --openapiv2_opt allow_merge=true,merge_file_name=simplebank \ - proto/*.proto + del docs\swagger\*.swagger.json & + del internal\delivery\grpc\pb & + protoc --proto_path=internal/delivery/grpc/proto --go_out=internal/delivery/grpc/pb --go_opt paths=source_relative \ + --go-grpc_out=internal/delivery/grpc/pb --go-grpc_opt paths=source_relative \ + --grpc-gateway_out=internal/delivery/grpc/pb --grpc-gateway_opt paths=source_relative \ + --openapiv2_out=docs/swagger --openapiv2_opt allow_merge=true,merge_file_name=simplebank \ + internal/delivery/grpc/proto/*.proto rerun_compose: docker compose down & diff --git a/api/main_test.go b/api/main_test.go deleted file mode 100644 index ae8f656..0000000 --- a/api/main_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package api - -import ( - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/token" - "github.com/cukhoaimon/SimpleBank/utils" - "github.com/stretchr/testify/require" - "os" - "testing" - "time" - - "github.com/gin-gonic/gin" -) - -func newTestServer(t *testing.T, store db.Store) *Server { - config := utils.Config{ - TokenDuration: 15 * time.Minute, - TokenSymmetricKey: utils.RandomString(32), - } - - pasetoMaker, err := token.NewPasetoMaker(config.TokenSymmetricKey) - require.Nil(t, err) - - server, err := NewServer(store, config) - require.Nil(t, err) - - server.tokenMaker = pasetoMaker - return server -} - -func TestMain(m *testing.M) { - gin.SetMode(gin.TestMode) - - os.Exit(m.Run()) -} diff --git a/api/server.go b/api/server.go deleted file mode 100644 index f583001..0000000 --- a/api/server.go +++ /dev/null @@ -1,67 +0,0 @@ -package api - -import ( - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/token" - "github.com/cukhoaimon/SimpleBank/utils" - "github.com/gin-gonic/gin" - "github.com/gin-gonic/gin/binding" - "github.com/go-playground/validator/v10" -) - -type Server struct { - store db.Store - config utils.Config - tokenMaker token.Maker - router *gin.Engine -} - -// NewServer will return new HTTP server and setup router -func NewServer(store db.Store, config utils.Config) (*Server, error) { - maker, err := token.NewPasetoMaker(config.TokenSymmetricKey) - if err != nil { - return nil, err - } - - server := &Server{ - store: store, - tokenMaker: maker, - config: config, - } - - if v, ok := binding.Validator.Engine().(*validator.Validate); ok { - err := v.RegisterValidation("currency", validCurrency) - if err != nil { - return nil, err - } - } - - server.setupRouter() - - return server, nil -} - -func (server *Server) setupRouter() { - router := gin.Default() - router.POST("/api/v1/user", server.createUser) - router.POST("/api/v1/user/login", server.loginUser) - router.POST("/api/v1/user/token/renew_access", server.renewAccessTokenUser) - - authRoutes := router.Group("/").Use(authMiddleware(server.tokenMaker)) - - authRoutes.GET("/api/v1/account", server.listAccount) - authRoutes.GET("/api/v1/account/:id", server.getAccount) - authRoutes.POST("/api/v1/account", server.createAccount) - - authRoutes.POST("/api/v1/transfer", server.createTransfer) - - server.router = router -} - -func (server *Server) Start(address string) error { - return server.router.Run(address) -} - -func errorResponse(err error) gin.H { - return gin.H{"error": err.Error()} -} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..df98e9c --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "github.com/cukhoaimon/SimpleBank/internal/app" + "github.com/cukhoaimon/SimpleBank/utils" + "log" +) + +func main() { + // load config + config, err := utils.LoadConfig(".") + if err != nil { + + log.Fatal(err.Error()) + } + + app.Run(config) +} diff --git a/doc/database.dbml b/docs/database.dbml similarity index 96% rename from doc/database.dbml rename to docs/database.dbml index 9902804..4320e8f 100644 --- a/doc/database.dbml +++ b/docs/database.dbml @@ -16,7 +16,7 @@ Table users as U { Table accounts as A { id bigserial [pk] - owner varchar [r ef: > U.username, not null] + owner varchar [ref: > U.username, not null] balance bigint [not null] currency varchar [not null] created_at timestamptz [not null, default: `now()`] diff --git a/doc/swagger/favicon-16x16.png b/docs/swagger/favicon-16x16.png similarity index 100% rename from doc/swagger/favicon-16x16.png rename to docs/swagger/favicon-16x16.png diff --git a/doc/swagger/favicon-32x32.png b/docs/swagger/favicon-32x32.png similarity index 100% rename from doc/swagger/favicon-32x32.png rename to docs/swagger/favicon-32x32.png diff --git a/doc/swagger/index.css b/docs/swagger/index.css similarity index 100% rename from doc/swagger/index.css rename to docs/swagger/index.css diff --git a/doc/swagger/index.html b/docs/swagger/index.html similarity index 100% rename from doc/swagger/index.html rename to docs/swagger/index.html diff --git a/doc/swagger/oauth2-redirect.html b/docs/swagger/oauth2-redirect.html similarity index 100% rename from doc/swagger/oauth2-redirect.html rename to docs/swagger/oauth2-redirect.html diff --git a/doc/swagger/simplebank.swagger.json b/docs/swagger/simplebank.swagger.json similarity index 100% rename from doc/swagger/simplebank.swagger.json rename to docs/swagger/simplebank.swagger.json diff --git a/doc/swagger/swagger-initializer.js b/docs/swagger/swagger-initializer.js similarity index 100% rename from doc/swagger/swagger-initializer.js rename to docs/swagger/swagger-initializer.js diff --git a/doc/swagger/swagger-ui-bundle.js b/docs/swagger/swagger-ui-bundle.js similarity index 100% rename from doc/swagger/swagger-ui-bundle.js rename to docs/swagger/swagger-ui-bundle.js diff --git a/doc/swagger/swagger-ui-bundle.js.map b/docs/swagger/swagger-ui-bundle.js.map similarity index 100% rename from doc/swagger/swagger-ui-bundle.js.map rename to docs/swagger/swagger-ui-bundle.js.map diff --git a/doc/swagger/swagger-ui-es-bundle-core.js b/docs/swagger/swagger-ui-es-bundle-core.js similarity index 100% rename from doc/swagger/swagger-ui-es-bundle-core.js rename to docs/swagger/swagger-ui-es-bundle-core.js diff --git a/doc/swagger/swagger-ui-es-bundle-core.js.map b/docs/swagger/swagger-ui-es-bundle-core.js.map similarity index 100% rename from doc/swagger/swagger-ui-es-bundle-core.js.map rename to docs/swagger/swagger-ui-es-bundle-core.js.map diff --git a/doc/swagger/swagger-ui-es-bundle.js b/docs/swagger/swagger-ui-es-bundle.js similarity index 100% rename from doc/swagger/swagger-ui-es-bundle.js rename to docs/swagger/swagger-ui-es-bundle.js diff --git a/doc/swagger/swagger-ui-es-bundle.js.map b/docs/swagger/swagger-ui-es-bundle.js.map similarity index 100% rename from doc/swagger/swagger-ui-es-bundle.js.map rename to docs/swagger/swagger-ui-es-bundle.js.map diff --git a/doc/swagger/swagger-ui-standalone-preset.js b/docs/swagger/swagger-ui-standalone-preset.js similarity index 100% rename from doc/swagger/swagger-ui-standalone-preset.js rename to docs/swagger/swagger-ui-standalone-preset.js diff --git a/doc/swagger/swagger-ui-standalone-preset.js.map b/docs/swagger/swagger-ui-standalone-preset.js.map similarity index 100% rename from doc/swagger/swagger-ui-standalone-preset.js.map rename to docs/swagger/swagger-ui-standalone-preset.js.map diff --git a/doc/swagger/swagger-ui.css b/docs/swagger/swagger-ui.css similarity index 100% rename from doc/swagger/swagger-ui.css rename to docs/swagger/swagger-ui.css diff --git a/doc/swagger/swagger-ui.css.map b/docs/swagger/swagger-ui.css.map similarity index 100% rename from doc/swagger/swagger-ui.css.map rename to docs/swagger/swagger-ui.css.map diff --git a/doc/swagger/swagger-ui.js b/docs/swagger/swagger-ui.js similarity index 100% rename from doc/swagger/swagger-ui.js rename to docs/swagger/swagger-ui.js diff --git a/doc/swagger/swagger-ui.js.map b/docs/swagger/swagger-ui.js.map similarity index 100% rename from doc/swagger/swagger-ui.js.map rename to docs/swagger/swagger-ui.js.map diff --git a/tools/tools.go b/framework/grpc/tools.go similarity index 95% rename from tools/tools.go rename to framework/grpc/tools.go index 709bd37..963ddaf 100644 --- a/tools/tools.go +++ b/framework/grpc/tools.go @@ -1,7 +1,7 @@ //go:build tools // +build tools -package tools +package grpc import ( _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway" diff --git a/gapi/server.go b/gapi/server.go deleted file mode 100644 index f53f619..0000000 --- a/gapi/server.go +++ /dev/null @@ -1,32 +0,0 @@ -package gapi - -import ( - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/pb" - "github.com/cukhoaimon/SimpleBank/token" - "github.com/cukhoaimon/SimpleBank/utils" -) - -// Server serves gRPC request -type Server struct { - pb.UnimplementedSimpleBankServer - config utils.Config - tokenMaker token.Maker - store db.Store -} - -// NewServer will return new gRPC server -func NewServer(store db.Store, config utils.Config) (*Server, error) { - maker, err := token.NewPasetoMaker(config.TokenSymmetricKey) - if err != nil { - return nil, err - } - - server := &Server{ - store: store, - tokenMaker: maker, - config: config, - } - - return server, nil -} diff --git a/internal/app/app.go b/internal/app/app.go new file mode 100644 index 0000000..26e151a --- /dev/null +++ b/internal/app/app.go @@ -0,0 +1,35 @@ +package app + +import ( + "database/sql" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/grpc" + "github.com/cukhoaimon/SimpleBank/utils" + "github.com/golang-migrate/migrate/v4/database/postgres" + _ "github.com/golang-migrate/migrate/v4/database/postgres" + _ "github.com/golang-migrate/migrate/v4/source/file" + _ "github.com/golang-migrate/migrate/v4/source/github" + _ "github.com/lib/pq" + "log" +) + +// Run will run simple bank app +func Run(config utils.Config) { + conn, err := sql.Open(config.DBDriver, config.DBSource) + if err != nil { + log.Fatal("The open connection to database process was encountered an error", err) + } + + driver, err := postgres.WithInstance(conn, &postgres.Config{}) + if err != nil { + log.Fatal("Error when create postgres driver instance: ", err) + } + + RunDBMigration(config.MigrationURL, config.PostgresDB, driver) + + store := db.NewStore(conn) + + go grpc.RunGatewayServer(store, config) + grpc.Run(store, config) + //http2.Run(store, config) +} diff --git a/internal/app/migration.go b/internal/app/migration.go new file mode 100644 index 0000000..ff5fda9 --- /dev/null +++ b/internal/app/migration.go @@ -0,0 +1,20 @@ +package app + +import ( + "github.com/golang-migrate/migrate/v4" + "github.com/golang-migrate/migrate/v4/database" + "log" +) + +func RunDBMigration(sourceURL string, databaseName string, databaseInstance database.Driver) { + migration, err := migrate.NewWithDatabaseInstance(sourceURL, databaseName, databaseInstance) + if err != nil { + log.Fatal("fail to create migration instance: ", err) + } + + if err = migration.Up(); err != nil && err.Error() != "no change" { + log.Fatal("fail to run migrate up: ", err) + } + + log.Println("migration is successfully") +} diff --git a/gapi/converter.go b/internal/delivery/grpc/gapi/converter.go similarity index 74% rename from gapi/converter.go rename to internal/delivery/grpc/gapi/converter.go index 27ae5cd..850c879 100644 --- a/gapi/converter.go +++ b/internal/delivery/grpc/gapi/converter.go @@ -1,8 +1,8 @@ package gapi import ( - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/pb" + "github.com/cukhoaimon/SimpleBank/internal/delivery/grpc/pb" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/gapi/error.go b/internal/delivery/grpc/gapi/error.go similarity index 100% rename from gapi/error.go rename to internal/delivery/grpc/gapi/error.go diff --git a/internal/delivery/grpc/gapi/handler.go b/internal/delivery/grpc/gapi/handler.go new file mode 100644 index 0000000..ff7faeb --- /dev/null +++ b/internal/delivery/grpc/gapi/handler.go @@ -0,0 +1,13 @@ +package gapi + +import ( + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/token" + "github.com/cukhoaimon/SimpleBank/utils" +) + +type Handler struct { + Config utils.Config + TokenMaker token.Maker + Store db.Store +} diff --git a/gapi/metadata.go b/internal/delivery/grpc/gapi/metadata.go similarity index 89% rename from gapi/metadata.go rename to internal/delivery/grpc/gapi/metadata.go index 966a7cf..e45927a 100644 --- a/gapi/metadata.go +++ b/internal/delivery/grpc/gapi/metadata.go @@ -16,7 +16,7 @@ const ( grpcGatewayClientIP = "x-forwarded-host" ) -func (server *Server) extractMetadata(ctx context.Context) *Metadata { +func (handler *Handler) extractMetadata(ctx context.Context) *Metadata { mtdt := &Metadata{} if md, ok := metadata.FromIncomingContext(ctx); ok { diff --git a/gapi/rpc_create_user.go b/internal/delivery/grpc/gapi/rpc_create_user.go similarity index 83% rename from gapi/rpc_create_user.go rename to internal/delivery/grpc/gapi/rpc_create_user.go index a04fb27..e33d792 100644 --- a/gapi/rpc_create_user.go +++ b/internal/delivery/grpc/gapi/rpc_create_user.go @@ -3,17 +3,17 @@ package gapi import ( "context" "errors" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/pb" + "github.com/cukhoaimon/SimpleBank/internal/delivery/grpc/pb" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/internal/usecase/val" "github.com/cukhoaimon/SimpleBank/utils" - "github.com/cukhoaimon/SimpleBank/val" "github.com/lib/pq" "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -func (server *Server) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { +func (handler *Handler) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { violations := validateCreateUserRequest(req) if violations != nil { return nil, invalidArgumentError(violations) @@ -31,7 +31,7 @@ func (server *Server) CreateUser(ctx context.Context, req *pb.CreateUserRequest) Email: req.GetEmail(), } - user, err := server.store.CreateUser(ctx, arg) + user, err := handler.Store.CreateUser(ctx, arg) if err != nil { var pqErr *pq.Error if errors.As(err, &pqErr) { diff --git a/gapi/rpc_login_user.go b/internal/delivery/grpc/gapi/rpc_login_user.go similarity index 75% rename from gapi/rpc_login_user.go rename to internal/delivery/grpc/gapi/rpc_login_user.go index 84ebe52..308ce9e 100644 --- a/gapi/rpc_login_user.go +++ b/internal/delivery/grpc/gapi/rpc_login_user.go @@ -4,23 +4,23 @@ import ( "context" "database/sql" "errors" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/pb" + "github.com/cukhoaimon/SimpleBank/internal/delivery/grpc/pb" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/internal/usecase/val" "github.com/cukhoaimon/SimpleBank/utils" - "github.com/cukhoaimon/SimpleBank/val" "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" ) -func (server *Server) LoginUser(ctx context.Context, req *pb.LoginUserRequest) (*pb.LoginUserResponse, error) { +func (handler *Handler) LoginUser(ctx context.Context, req *pb.LoginUserRequest) (*pb.LoginUserResponse, error) { violations := validateLoginUserRequest(req) if violations != nil { return nil, invalidArgumentError(violations) } - user, err := server.store.GetUser(ctx, req.GetUsername()) + user, err := handler.Store.GetUser(ctx, req.GetUsername()) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, status.Errorf(codes.NotFound, "user [%s] is not found in database", req.GetUsername()) @@ -35,17 +35,17 @@ func (server *Server) LoginUser(ctx context.Context, req *pb.LoginUserRequest) ( } - token, accessTokenPayload, err := server.tokenMaker.CreateToken(req.Username, server.config.TokenDuration) + token, accessTokenPayload, err := handler.TokenMaker.CreateToken(req.Username, handler.Config.TokenDuration) if err != nil { return nil, status.Error(codes.Internal, "fail to create access token") } - refreshToken, refreshTokenPayload, err := server.tokenMaker.CreateToken(req.Username, server.config.RefreshTokenDuration) + refreshToken, refreshTokenPayload, err := handler.TokenMaker.CreateToken(req.Username, handler.Config.RefreshTokenDuration) if err != nil { return nil, status.Error(codes.Internal, "fail to create refresh access token") } - metadata := server.extractMetadata(ctx) + metadata := handler.extractMetadata(ctx) arg := db.CreateSessionParams{ ID: accessTokenPayload.Id, Username: accessTokenPayload.Username, @@ -56,7 +56,7 @@ func (server *Server) LoginUser(ctx context.Context, req *pb.LoginUserRequest) ( ExpiresAt: refreshTokenPayload.ExpiredAt, } - session, err := server.store.CreateSession(ctx, arg) + session, err := handler.Store.CreateSession(ctx, arg) if err != nil { return nil, status.Error(codes.Internal, "fail to create session") } diff --git a/pb/rpc_create_user.pb.go b/internal/delivery/grpc/pb/rpc_create_user.pb.go similarity index 92% rename from pb/rpc_create_user.pb.go rename to internal/delivery/grpc/pb/rpc_create_user.pb.go index a76cf71..dd1ecf4 100644 --- a/pb/rpc_create_user.pb.go +++ b/internal/delivery/grpc/pb/rpc_create_user.pb.go @@ -25,10 +25,10 @@ type CreateUserRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - FullName string `protobuf:"bytes,2,opt,name=full_name,json=fullName,proto3" json:"full_name,omitempty"` - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + Username string `pb:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + FullName string `pb:"bytes,2,opt,name=full_name,json=fullName,proto3" json:"full_name,omitempty"` + Email string `pb:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Password string `pb:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` } func (x *CreateUserRequest) Reset() { @@ -96,7 +96,7 @@ type CreateUserResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + User *User `pb:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` } func (x *CreateUserResponse) Reset() { @@ -154,10 +154,10 @@ var file_rpc_create_user_proto_rawDesc = []byte{ 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x32, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x42, 0x25, 0x5a, 0x23, 0x67, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x6b, 0x68, 0x6f, 0x61, 0x69, 0x6d, 0x6f, 0x6e, 0x2f, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x61, 0x6e, 0x6b, 0x2f, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pb/rpc_login_user.pb.go b/internal/delivery/grpc/pb/rpc_login_user.pb.go similarity index 87% rename from pb/rpc_login_user.pb.go rename to internal/delivery/grpc/pb/rpc_login_user.pb.go index a354648..5f7d8a1 100644 --- a/pb/rpc_login_user.pb.go +++ b/internal/delivery/grpc/pb/rpc_login_user.pb.go @@ -26,8 +26,8 @@ type LoginUserRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Username string `pb:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `pb:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } func (x *LoginUserRequest) Reset() { @@ -81,12 +81,12 @@ type LoginUserResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` - AccessToken string `protobuf:"bytes,3,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` - RefreshToken string `protobuf:"bytes,4,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"` - AccessTokenExpiresAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=access_token_expires_at,json=accessTokenExpiresAt,proto3" json:"access_token_expires_at,omitempty"` - RefreshTokenExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=refresh_token_expires_at,json=refreshTokenExpiresAt,proto3" json:"refresh_token_expires_at,omitempty"` + User *User `pb:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + SessionId string `pb:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + AccessToken string `pb:"bytes,3,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` + RefreshToken string `pb:"bytes,4,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"` + AccessTokenExpiresAt *timestamppb.Timestamp `pb:"bytes,5,opt,name=access_token_expires_at,json=accessTokenExpiresAt,proto3" json:"access_token_expires_at,omitempty"` + RefreshTokenExpiresAt *timestamppb.Timestamp `pb:"bytes,6,opt,name=refresh_token_expires_at,json=refreshTokenExpiresAt,proto3" json:"refresh_token_expires_at,omitempty"` } func (x *LoginUserResponse) Reset() { @@ -195,10 +195,10 @@ var file_rpc_login_user_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x15, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x45, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x42, 0x25, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x6b, 0x68, 0x6f, 0x61, 0x69, 0x6d, 0x6f, 0x6e, 0x2f, - 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -218,12 +218,12 @@ var file_rpc_login_user_proto_goTypes = []interface{}{ (*LoginUserRequest)(nil), // 0: pb.LoginUserRequest (*LoginUserResponse)(nil), // 1: pb.LoginUserResponse (*User)(nil), // 2: pb.User - (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 3: google.pb.Timestamp } var file_rpc_login_user_proto_depIdxs = []int32{ 2, // 0: pb.LoginUserResponse.user:type_name -> pb.User - 3, // 1: pb.LoginUserResponse.access_token_expires_at:type_name -> google.protobuf.Timestamp - 3, // 2: pb.LoginUserResponse.refresh_token_expires_at:type_name -> google.protobuf.Timestamp + 3, // 1: pb.LoginUserResponse.access_token_expires_at:type_name -> google.pb.Timestamp + 3, // 2: pb.LoginUserResponse.refresh_token_expires_at:type_name -> google.pb.Timestamp 3, // [3:3] is the sub-list for method output_type 3, // [3:3] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name diff --git a/pb/service_simple_bank.pb.go b/internal/delivery/grpc/pb/service_simple_bank.pb.go similarity index 95% rename from pb/service_simple_bank.pb.go rename to internal/delivery/grpc/pb/service_simple_bank.pb.go index 5b1de9f..c0af01b 100644 --- a/pb/service_simple_bank.pb.go +++ b/internal/delivery/grpc/pb/service_simple_bank.pb.go @@ -45,16 +45,17 @@ var file_service_simple_bank_proto_rawDesc = []byte{ 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, - 0x65, 0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x42, 0x8b, 0x01, 0x92, 0x41, 0x63, 0x12, 0x61, + 0x65, 0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x42, 0x91, 0x01, 0x92, 0x41, 0x63, 0x12, 0x61, 0x0a, 0x0a, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x61, 0x6e, 0x6b, 0x22, 0x4e, 0x0a, 0x11, 0x4e, 0x67, 0x75, 0x79, 0x65, 0x6e, 0x20, 0x48, 0x6f, 0x61, 0x6e, 0x67, 0x20, 0x50, 0x68, 0x75, 0x63, 0x12, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x6b, 0x68, 0x6f, 0x61, 0x69, 0x6d, 0x6f, 0x6e, 0x1a, 0x1a, 0x68, 0x6f, 0x61, 0x6e, 0x67, 0x70, 0x68, 0x75, 0x63, 0x6e, 0x68, 0x70, 0x31, 0x33, 0x31, 0x32, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x32, 0x03, 0x31, 0x2e, - 0x30, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, + 0x30, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x6b, 0x68, 0x6f, 0x61, 0x69, 0x6d, 0x6f, 0x6e, 0x2f, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x42, - 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var file_service_simple_bank_proto_goTypes = []interface{}{ diff --git a/pb/service_simple_bank.pb.gw.go b/internal/delivery/grpc/pb/service_simple_bank.pb.gw.go similarity index 100% rename from pb/service_simple_bank.pb.gw.go rename to internal/delivery/grpc/pb/service_simple_bank.pb.gw.go diff --git a/pb/service_simple_bank_grpc.pb.go b/internal/delivery/grpc/pb/service_simple_bank_grpc.pb.go similarity index 100% rename from pb/service_simple_bank_grpc.pb.go rename to internal/delivery/grpc/pb/service_simple_bank_grpc.pb.go diff --git a/pb/user.pb.go b/internal/delivery/grpc/pb/user.pb.go similarity index 84% rename from pb/user.pb.go rename to internal/delivery/grpc/pb/user.pb.go index 3623d28..59106c1 100644 --- a/pb/user.pb.go +++ b/internal/delivery/grpc/pb/user.pb.go @@ -26,11 +26,11 @@ type User struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - FullName string `protobuf:"bytes,2,opt,name=full_name,json=fullName,proto3" json:"full_name,omitempty"` - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - PasswordChangedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=password_changed_at,json=passwordChangedAt,proto3" json:"password_changed_at,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Username string `pb:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + FullName string `pb:"bytes,2,opt,name=full_name,json=fullName,proto3" json:"full_name,omitempty"` + Email string `pb:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + PasswordChangedAt *timestamppb.Timestamp `pb:"bytes,4,opt,name=password_changed_at,json=passwordChangedAt,proto3" json:"password_changed_at,omitempty"` + CreatedAt *timestamppb.Timestamp `pb:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` } func (x *User) Reset() { @@ -120,9 +120,10 @@ var file_user_proto_rawDesc = []byte{ 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x42, 0x25, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, + 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x6b, 0x68, 0x6f, 0x61, 0x69, 0x6d, 0x6f, 0x6e, 0x2f, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, - 0x42, 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x61, 0x6e, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -140,11 +141,11 @@ func file_user_proto_rawDescGZIP() []byte { var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_user_proto_goTypes = []interface{}{ (*User)(nil), // 0: pb.User - (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 1: google.pb.Timestamp } var file_user_proto_depIdxs = []int32{ - 1, // 0: pb.User.password_changed_at:type_name -> google.protobuf.Timestamp - 1, // 1: pb.User.created_at:type_name -> google.protobuf.Timestamp + 1, // 0: pb.User.password_changed_at:type_name -> google.pb.Timestamp + 1, // 1: pb.User.created_at:type_name -> google.pb.Timestamp 2, // [2:2] is the sub-list for method output_type 2, // [2:2] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name diff --git a/proto/google/api/annotations.proto b/internal/delivery/grpc/proto/google/api/annotations.proto similarity index 100% rename from proto/google/api/annotations.proto rename to internal/delivery/grpc/proto/google/api/annotations.proto diff --git a/proto/google/api/field_behavior.proto b/internal/delivery/grpc/proto/google/api/field_behavior.proto similarity index 100% rename from proto/google/api/field_behavior.proto rename to internal/delivery/grpc/proto/google/api/field_behavior.proto diff --git a/proto/google/api/http.proto b/internal/delivery/grpc/proto/google/api/http.proto similarity index 100% rename from proto/google/api/http.proto rename to internal/delivery/grpc/proto/google/api/http.proto diff --git a/proto/google/api/httpbody.proto b/internal/delivery/grpc/proto/google/api/httpbody.proto similarity index 100% rename from proto/google/api/httpbody.proto rename to internal/delivery/grpc/proto/google/api/httpbody.proto diff --git a/proto/protoc-gen-openapiv2/options/BUILD.bazel b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/BUILD.bazel similarity index 100% rename from proto/protoc-gen-openapiv2/options/BUILD.bazel rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/BUILD.bazel diff --git a/proto/protoc-gen-openapiv2/options/annotations.pb.go b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.pb.go similarity index 92% rename from proto/protoc-gen-openapiv2/options/annotations.pb.go rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.pb.go index 52b1def..4d43bd2 100644 --- a/proto/protoc-gen-openapiv2/options/annotations.pb.go +++ b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.pb.go @@ -65,7 +65,7 @@ var file_protoc_gen_openapiv2_options_annotations_proto_extTypes = []protoimpl.E // Extension fields to descriptorpb.FileOptions. var ( - // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project. + // ID assigned by pb-global-extension-registry@google.com for gRPC-Gateway project. // // All IDs are the same, as assigned. It is okay that they are the same, as they extend // different descriptor messages. @@ -76,7 +76,7 @@ var ( // Extension fields to descriptorpb.MethodOptions. var ( - // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project. + // ID assigned by pb-global-extension-registry@google.com for gRPC-Gateway project. // // All IDs are the same, as assigned. It is okay that they are the same, as they extend // different descriptor messages. @@ -87,7 +87,7 @@ var ( // Extension fields to descriptorpb.MessageOptions. var ( - // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project. + // ID assigned by pb-global-extension-registry@google.com for gRPC-Gateway project. // // All IDs are the same, as assigned. It is okay that they are the same, as they extend // different descriptor messages. @@ -98,7 +98,7 @@ var ( // Extension fields to descriptorpb.ServiceOptions. var ( - // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project. + // ID assigned by pb-global-extension-registry@google.com for gRPC-Gateway project. // // All IDs are the same, as assigned. It is okay that they are the same, as they extend // different descriptor messages. @@ -109,7 +109,7 @@ var ( // Extension fields to descriptorpb.FieldOptions. var ( - // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project. + // ID assigned by pb-global-extension-registry@google.com for gRPC-Gateway project. // // All IDs are the same, as assigned. It is okay that they are the same, as they extend // different descriptor messages. @@ -180,11 +180,11 @@ var file_protoc_gen_openapiv2_options_annotations_proto_rawDesc = []byte{ } var file_protoc_gen_openapiv2_options_annotations_proto_goTypes = []interface{}{ - (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions - (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions - (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions - (*descriptorpb.ServiceOptions)(nil), // 3: google.protobuf.ServiceOptions - (*descriptorpb.FieldOptions)(nil), // 4: google.protobuf.FieldOptions + (*descriptorpb.FileOptions)(nil), // 0: google.pb.FileOptions + (*descriptorpb.MethodOptions)(nil), // 1: google.pb.MethodOptions + (*descriptorpb.MessageOptions)(nil), // 2: google.pb.MessageOptions + (*descriptorpb.ServiceOptions)(nil), // 3: google.pb.ServiceOptions + (*descriptorpb.FieldOptions)(nil), // 4: google.pb.FieldOptions (*Swagger)(nil), // 5: grpc.gateway.protoc_gen_openapiv2.options.Swagger (*Operation)(nil), // 6: grpc.gateway.protoc_gen_openapiv2.options.Operation (*Schema)(nil), // 7: grpc.gateway.protoc_gen_openapiv2.options.Schema @@ -192,11 +192,11 @@ var file_protoc_gen_openapiv2_options_annotations_proto_goTypes = []interface{}{ (*JSONSchema)(nil), // 9: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema } var file_protoc_gen_openapiv2_options_annotations_proto_depIdxs = []int32{ - 0, // 0: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger:extendee -> google.protobuf.FileOptions - 1, // 1: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation:extendee -> google.protobuf.MethodOptions - 2, // 2: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema:extendee -> google.protobuf.MessageOptions - 3, // 3: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag:extendee -> google.protobuf.ServiceOptions - 4, // 4: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field:extendee -> google.protobuf.FieldOptions + 0, // 0: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger:extendee -> google.pb.FileOptions + 1, // 1: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation:extendee -> google.pb.MethodOptions + 2, // 2: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema:extendee -> google.pb.MessageOptions + 3, // 3: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag:extendee -> google.pb.ServiceOptions + 4, // 4: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field:extendee -> google.pb.FieldOptions 5, // 5: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger 6, // 6: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation 7, // 7: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Schema diff --git a/proto/protoc-gen-openapiv2/options/annotations.proto b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.proto similarity index 100% rename from proto/protoc-gen-openapiv2/options/annotations.proto rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.proto diff --git a/proto/protoc-gen-openapiv2/options/annotations.swagger.json b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.swagger.json similarity index 100% rename from proto/protoc-gen-openapiv2/options/annotations.swagger.json rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/annotations.swagger.json diff --git a/proto/protoc-gen-openapiv2/options/openapiv2.pb.go b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.pb.go similarity index 91% rename from proto/protoc-gen-openapiv2/options/openapiv2.pb.go rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.pb.go index 4ad7446..d47fbc7 100644 --- a/proto/protoc-gen-openapiv2/options/openapiv2.pb.go +++ b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.pb.go @@ -393,15 +393,15 @@ type Swagger struct { // Specifies the OpenAPI Specification version being used. It can be // used by the OpenAPI UI and other clients to interpret the API listing. The // value MUST be "2.0". - Swagger string `protobuf:"bytes,1,opt,name=swagger,proto3" json:"swagger,omitempty"` + Swagger string `pb:"bytes,1,opt,name=swagger,proto3" json:"swagger,omitempty"` // Provides metadata about the API. The metadata can be used by the // clients if needed. - Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` + Info *Info `pb:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` // The host (name or ip) serving the API. This MUST be the host only and does // not include the scheme nor sub-paths. It MAY include a port. If the host is // not included, the host serving the documentation is to be used (including // the port). The host does not support path templating. - Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"` + Host string `pb:"bytes,3,opt,name=host,proto3" json:"host,omitempty"` // The base path on which the API is served, which is relative to the host. If // it is not included, the API is served directly under the host. The value // MUST start with a leading slash (/). The basePath does not support path @@ -411,38 +411,38 @@ type Swagger struct { // with relatively generated OpenAPI paths, the `base_path` prefix must be // manually removed from your `google.api.http` paths and your code changed to // serve the API from the `base_path`. - BasePath string `protobuf:"bytes,4,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"` + BasePath string `pb:"bytes,4,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"` // The transfer protocol of the API. Values MUST be from the list: "http", // "https", "ws", "wss". If the schemes is not included, the default scheme to // be used is the one used to access the OpenAPI definition itself. - Schemes []Scheme `protobuf:"varint,5,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"` + Schemes []Scheme `pb:"varint,5,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"` // A list of MIME types the APIs can consume. This is global to all APIs but // can be overridden on specific API calls. Value MUST be as described under // Mime Types. - Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"` + Consumes []string `pb:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"` // A list of MIME types the APIs can produce. This is global to all APIs but // can be overridden on specific API calls. Value MUST be as described under // Mime Types. - Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"` + Produces []string `pb:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"` // An object to hold responses that can be used across operations. This // property does not define global responses for all operations. - Responses map[string]*Response `protobuf:"bytes,10,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Responses map[string]*Response `pb:"bytes,10,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Security scheme definitions that can be used across the specification. - SecurityDefinitions *SecurityDefinitions `protobuf:"bytes,11,opt,name=security_definitions,json=securityDefinitions,proto3" json:"security_definitions,omitempty"` + SecurityDefinitions *SecurityDefinitions `pb:"bytes,11,opt,name=security_definitions,json=securityDefinitions,proto3" json:"security_definitions,omitempty"` // A declaration of which security schemes are applied for the API as a whole. // The list of values describes alternative security schemes that can be used // (that is, there is a logical OR between the security requirements). // Individual operations can override this definition. - Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"` + Security []*SecurityRequirement `pb:"bytes,12,rep,name=security,proto3" json:"security,omitempty"` // A list of tags for API documentation control. Tags can be used for logical // grouping of operations by resources or any other qualifier. - Tags []*Tag `protobuf:"bytes,13,rep,name=tags,proto3" json:"tags,omitempty"` + Tags []*Tag `pb:"bytes,13,rep,name=tags,proto3" json:"tags,omitempty"` // Additional external documentation. - ExternalDocs *ExternalDocumentation `protobuf:"bytes,14,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` + ExternalDocs *ExternalDocumentation `pb:"bytes,14,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,15,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,15,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Swagger) Reset() { @@ -600,52 +600,52 @@ type Operation struct { // A list of tags for API documentation control. Tags can be used for logical // grouping of operations by resources or any other qualifier. - Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` + Tags []string `pb:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` // A short summary of what the operation does. For maximum readability in the // swagger-ui, this field SHOULD be less than 120 characters. - Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` + Summary string `pb:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` // A verbose explanation of the operation behavior. GFM syntax can be used for // rich text representation. - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Additional external documentation for this operation. - ExternalDocs *ExternalDocumentation `protobuf:"bytes,4,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` + ExternalDocs *ExternalDocumentation `pb:"bytes,4,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` // Unique string used to identify the operation. The id MUST be unique among // all operations described in the API. Tools and libraries MAY use the // operationId to uniquely identify an operation, therefore, it is recommended // to follow common programming naming conventions. - OperationId string `protobuf:"bytes,5,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` + OperationId string `pb:"bytes,5,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` // A list of MIME types the operation can consume. This overrides the consumes // definition at the OpenAPI Object. An empty value MAY be used to clear the // global definition. Value MUST be as described under Mime Types. - Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"` + Consumes []string `pb:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"` // A list of MIME types the operation can produce. This overrides the produces // definition at the OpenAPI Object. An empty value MAY be used to clear the // global definition. Value MUST be as described under Mime Types. - Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"` + Produces []string `pb:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"` // The list of possible responses as they are returned from executing this // operation. - Responses map[string]*Response `protobuf:"bytes,9,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Responses map[string]*Response `pb:"bytes,9,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // The transfer protocol for the operation. Values MUST be from the list: // "http", "https", "ws", "wss". The value overrides the OpenAPI Object // schemes definition. - Schemes []Scheme `protobuf:"varint,10,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"` + Schemes []Scheme `pb:"varint,10,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"` // Declares this operation to be deprecated. Usage of the declared operation // should be refrained. Default value is false. - Deprecated bool `protobuf:"varint,11,opt,name=deprecated,proto3" json:"deprecated,omitempty"` + Deprecated bool `pb:"varint,11,opt,name=deprecated,proto3" json:"deprecated,omitempty"` // A declaration of which security schemes are applied for this operation. The // list of values describes alternative security schemes that can be used // (that is, there is a logical OR between the security requirements). This // definition overrides any declared top-level security. To remove a top-level // security declaration, an empty array can be used. - Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"` + Security []*SecurityRequirement `pb:"bytes,12,rep,name=security,proto3" json:"security,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,13,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,13,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Custom parameters such as HTTP request headers. // See: https://swagger.io/docs/specification/2-0/describing-parameters/ // and https://swagger.io/specification/v2/#parameter-object. - Parameters *Parameters `protobuf:"bytes,14,opt,name=parameters,proto3" json:"parameters,omitempty"` + Parameters *Parameters `pb:"bytes,14,opt,name=parameters,proto3" json:"parameters,omitempty"` } func (x *Operation) Reset() { @@ -783,7 +783,7 @@ type Parameters struct { // `Headers` is one or more HTTP header parameter. // See: https://swagger.io/docs/specification/2-0/describing-parameters/#header-parameters - Headers []*HeaderParameter `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` + Headers []*HeaderParameter `pb:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` } func (x *Parameters) Reset() { @@ -833,16 +833,16 @@ type HeaderParameter struct { unknownFields protoimpl.UnknownFields // `Name` is the header name. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `pb:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // `Description` is a short description of the header. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // `Type` is the type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported. // See: https://swagger.io/specification/v2/#parameterType. - Type HeaderParameter_Type `protobuf:"varint,3,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter_Type" json:"type,omitempty"` + Type HeaderParameter_Type `pb:"varint,3,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter_Type" json:"type,omitempty"` // `Format` The extending format for the previously mentioned type. - Format string `protobuf:"bytes,4,opt,name=format,proto3" json:"format,omitempty"` + Format string `pb:"bytes,4,opt,name=format,proto3" json:"format,omitempty"` // `Required` indicates if the header is optional - Required bool `protobuf:"varint,5,opt,name=required,proto3" json:"required,omitempty"` + Required bool `pb:"varint,5,opt,name=required,proto3" json:"required,omitempty"` } func (x *HeaderParameter) Reset() { @@ -921,17 +921,17 @@ type Header struct { unknownFields protoimpl.UnknownFields // `Description` is a short description of the header. - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` // The type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported. - Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Type string `pb:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // `Format` The extending format for the previously mentioned type. - Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` + Format string `pb:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` // `Default` Declares the value of the header that the server will use if none is provided. // See: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2. // Unlike JSON Schema this value MUST conform to the defined type for the header. - Default string `protobuf:"bytes,6,opt,name=default,proto3" json:"default,omitempty"` + Default string `pb:"bytes,6,opt,name=default,proto3" json:"default,omitempty"` // 'Pattern' See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3. - Pattern string `protobuf:"bytes,13,opt,name=pattern,proto3" json:"pattern,omitempty"` + Pattern string `pb:"bytes,13,opt,name=pattern,proto3" json:"pattern,omitempty"` } func (x *Header) Reset() { @@ -1011,21 +1011,21 @@ type Response struct { // `Description` is a short description of the response. // GFM syntax can be used for rich text representation. - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` // `Schema` optionally defines the structure of the response. // If `Schema` is not provided, it means there is no content to the response. - Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"` + Schema *Schema `pb:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"` // `Headers` A list of headers that are sent with the response. // `Header` name is expected to be a string in the canonical format of the MIME header key // See: https://golang.org/pkg/net/textproto/#CanonicalMIMEHeaderKey - Headers map[string]*Header `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Headers map[string]*Header `pb:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // `Examples` gives per-mimetype response examples. // See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#example-object - Examples map[string]string `protobuf:"bytes,4,rep,name=examples,proto3" json:"examples,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Examples map[string]string `pb:"bytes,4,rep,name=examples,proto3" json:"examples,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,5,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,5,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Response) Reset() { @@ -1124,23 +1124,23 @@ type Info struct { unknownFields protoimpl.UnknownFields // The title of the application. - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Title string `pb:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` // A short description of the application. GFM syntax can be used for rich // text representation. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // The Terms of Service for the API. - TermsOfService string `protobuf:"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3" json:"terms_of_service,omitempty"` + TermsOfService string `pb:"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3" json:"terms_of_service,omitempty"` // The contact information for the exposed API. - Contact *Contact `protobuf:"bytes,4,opt,name=contact,proto3" json:"contact,omitempty"` + Contact *Contact `pb:"bytes,4,opt,name=contact,proto3" json:"contact,omitempty"` // The license information for the exposed API. - License *License `protobuf:"bytes,5,opt,name=license,proto3" json:"license,omitempty"` + License *License `pb:"bytes,5,opt,name=license,proto3" json:"license,omitempty"` // Provides the version of the application API (not to be confused // with the specification version). - Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"` + Version string `pb:"bytes,6,opt,name=version,proto3" json:"version,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,7,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,7,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Info) Reset() { @@ -1248,13 +1248,13 @@ type Contact struct { unknownFields protoimpl.UnknownFields // The identifying name of the contact person/organization. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `pb:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The URL pointing to the contact information. MUST be in the format of a // URL. - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + Url string `pb:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` // The email address of the contact person/organization. MUST be in the format // of an email address. - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Email string `pb:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` } func (x *Contact) Reset() { @@ -1333,9 +1333,9 @@ type License struct { unknownFields protoimpl.UnknownFields // The license name used for the API. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `pb:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // A URL to the license used for the API. MUST be in the format of a URL. - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + Url string `pb:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` } func (x *License) Reset() { @@ -1406,10 +1406,10 @@ type ExternalDocumentation struct { // A short description of the target documentation. GFM syntax can be used for // rich text representation. - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` // The URL for the target documentation. Value MUST be in the format // of a URL. - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + Url string `pb:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` } func (x *ExternalDocumentation) Reset() { @@ -1466,24 +1466,24 @@ type Schema struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - JsonSchema *JSONSchema `protobuf:"bytes,1,opt,name=json_schema,json=jsonSchema,proto3" json:"json_schema,omitempty"` + JsonSchema *JSONSchema `pb:"bytes,1,opt,name=json_schema,json=jsonSchema,proto3" json:"json_schema,omitempty"` // Adds support for polymorphism. The discriminator is the schema property // name that is used to differentiate between other schema that inherit this // schema. The property name used MUST be defined at this schema and it MUST // be in the required property list. When used, the value MUST be the name of // this schema or any schema that inherits it. - Discriminator string `protobuf:"bytes,2,opt,name=discriminator,proto3" json:"discriminator,omitempty"` + Discriminator string `pb:"bytes,2,opt,name=discriminator,proto3" json:"discriminator,omitempty"` // Relevant only for Schema "properties" definitions. Declares the property as // "read only". This means that it MAY be sent as part of a response but MUST // NOT be sent as part of the request. Properties marked as readOnly being // true SHOULD NOT be in the required list of the defined schema. Default // value is false. - ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"` + ReadOnly bool `pb:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"` // Additional external documentation for this schema. - ExternalDocs *ExternalDocumentation `protobuf:"bytes,5,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` + ExternalDocs *ExternalDocumentation `pb:"bytes,5,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` // A free-form property to include an example of an instance for this schema in JSON. // This is copied verbatim to the output. - Example string `protobuf:"bytes,6,opt,name=example,proto3" json:"example,omitempty"` + Example string `pb:"bytes,6,opt,name=example,proto3" json:"example,omitempty"` } func (x *Schema) Reset() { @@ -1591,49 +1591,49 @@ type JSONSchema struct { // be used verbatim in the output. // For example: // - // `ref: ".google.protobuf.Timestamp"`. - Ref string `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` + // `ref: ".google.pb.Timestamp"`. + Ref string `pb:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` // The title of the schema. - Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"` + Title string `pb:"bytes,5,opt,name=title,proto3" json:"title,omitempty"` // A short description of the schema. - Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` - Default string `protobuf:"bytes,7,opt,name=default,proto3" json:"default,omitempty"` - ReadOnly bool `protobuf:"varint,8,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"` + Description string `pb:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` + Default string `pb:"bytes,7,opt,name=default,proto3" json:"default,omitempty"` + ReadOnly bool `pb:"varint,8,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"` // A free-form property to include a JSON example of this field. This is copied // verbatim to the output swagger.json. Quotes must be escaped. // This property is the same for 2.0 and 3.0.0 https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaObject https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject - Example string `protobuf:"bytes,9,opt,name=example,proto3" json:"example,omitempty"` - MultipleOf float64 `protobuf:"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3" json:"multiple_of,omitempty"` + Example string `pb:"bytes,9,opt,name=example,proto3" json:"example,omitempty"` + MultipleOf float64 `pb:"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3" json:"multiple_of,omitempty"` // Maximum represents an inclusive upper limit for a numeric instance. The // value of MUST be a number, - Maximum float64 `protobuf:"fixed64,11,opt,name=maximum,proto3" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3" json:"exclusive_maximum,omitempty"` + Maximum float64 `pb:"fixed64,11,opt,name=maximum,proto3" json:"maximum,omitempty"` + ExclusiveMaximum bool `pb:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3" json:"exclusive_maximum,omitempty"` // minimum represents an inclusive lower limit for a numeric instance. The // value of MUST be a number, - Minimum float64 `protobuf:"fixed64,13,opt,name=minimum,proto3" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3" json:"exclusive_minimum,omitempty"` - MaxLength uint64 `protobuf:"varint,15,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` - MinLength uint64 `protobuf:"varint,16,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,17,opt,name=pattern,proto3" json:"pattern,omitempty"` - MaxItems uint64 `protobuf:"varint,20,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` - MinItems uint64 `protobuf:"varint,21,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,22,opt,name=unique_items,json=uniqueItems,proto3" json:"unique_items,omitempty"` - MaxProperties uint64 `protobuf:"varint,24,opt,name=max_properties,json=maxProperties,proto3" json:"max_properties,omitempty"` - MinProperties uint64 `protobuf:"varint,25,opt,name=min_properties,json=minProperties,proto3" json:"min_properties,omitempty"` - Required []string `protobuf:"bytes,26,rep,name=required,proto3" json:"required,omitempty"` + Minimum float64 `pb:"fixed64,13,opt,name=minimum,proto3" json:"minimum,omitempty"` + ExclusiveMinimum bool `pb:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3" json:"exclusive_minimum,omitempty"` + MaxLength uint64 `pb:"varint,15,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` + MinLength uint64 `pb:"varint,16,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` + Pattern string `pb:"bytes,17,opt,name=pattern,proto3" json:"pattern,omitempty"` + MaxItems uint64 `pb:"varint,20,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` + MinItems uint64 `pb:"varint,21,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` + UniqueItems bool `pb:"varint,22,opt,name=unique_items,json=uniqueItems,proto3" json:"unique_items,omitempty"` + MaxProperties uint64 `pb:"varint,24,opt,name=max_properties,json=maxProperties,proto3" json:"max_properties,omitempty"` + MinProperties uint64 `pb:"varint,25,opt,name=min_properties,json=minProperties,proto3" json:"min_properties,omitempty"` + Required []string `pb:"bytes,26,rep,name=required,proto3" json:"required,omitempty"` // Items in 'array' must be unique. - Array []string `protobuf:"bytes,34,rep,name=array,proto3" json:"array,omitempty"` - Type []JSONSchema_JSONSchemaSimpleTypes `protobuf:"varint,35,rep,packed,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.JSONSchema_JSONSchemaSimpleTypes" json:"type,omitempty"` + Array []string `pb:"bytes,34,rep,name=array,proto3" json:"array,omitempty"` + Type []JSONSchema_JSONSchemaSimpleTypes `pb:"varint,35,rep,packed,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.JSONSchema_JSONSchemaSimpleTypes" json:"type,omitempty"` // `Format` - Format string `protobuf:"bytes,36,opt,name=format,proto3" json:"format,omitempty"` + Format string `pb:"bytes,36,opt,name=format,proto3" json:"format,omitempty"` // Items in `enum` must be unique https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1 - Enum []string `protobuf:"bytes,46,rep,name=enum,proto3" json:"enum,omitempty"` + Enum []string `pb:"bytes,46,rep,name=enum,proto3" json:"enum,omitempty"` // Additional field level properties used when generating the OpenAPI v2 file. - FieldConfiguration *JSONSchema_FieldConfiguration `protobuf:"bytes,1001,opt,name=field_configuration,json=fieldConfiguration,proto3" json:"field_configuration,omitempty"` + FieldConfiguration *JSONSchema_FieldConfiguration `pb:"bytes,1001,opt,name=field_configuration,json=fieldConfiguration,proto3" json:"field_configuration,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,48,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,48,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *JSONSchema) Reset() { @@ -1861,16 +1861,16 @@ type Tag struct { // The name of the tag. Use it to allow override of the name of a // global Tag object, then use that name to reference the tag throughout the // OpenAPI file. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `pb:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // A short description for the tag. GFM syntax can be used for rich text // representation. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Additional external documentation for this tag. - ExternalDocs *ExternalDocumentation `protobuf:"bytes,3,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` + ExternalDocs *ExternalDocumentation `pb:"bytes,3,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,4,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,4,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Tag) Reset() { @@ -1948,7 +1948,7 @@ type SecurityDefinitions struct { // A single security scheme definition, mapping a "name" to the scheme it // defines. - Security map[string]*SecurityScheme `protobuf:"bytes,1,rep,name=security,proto3" json:"security,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Security map[string]*SecurityScheme `pb:"bytes,1,rep,name=security,proto3" json:"security,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *SecurityDefinitions) Reset() { @@ -2006,35 +2006,35 @@ type SecurityScheme struct { // The type of the security scheme. Valid values are "basic", // "apiKey" or "oauth2". - Type SecurityScheme_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Type" json:"type,omitempty"` + Type SecurityScheme_Type `pb:"varint,1,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Type" json:"type,omitempty"` // A short description for security scheme. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Description string `pb:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // The name of the header or query parameter to be used. // Valid for apiKey. - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Name string `pb:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // The location of the API key. Valid values are "query" or // "header". // Valid for apiKey. - In SecurityScheme_In `protobuf:"varint,4,opt,name=in,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_In" json:"in,omitempty"` + In SecurityScheme_In `pb:"varint,4,opt,name=in,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_In" json:"in,omitempty"` // The flow used by the OAuth2 security scheme. Valid values are // "implicit", "password", "application" or "accessCode". // Valid for oauth2. - Flow SecurityScheme_Flow `protobuf:"varint,5,opt,name=flow,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Flow" json:"flow,omitempty"` + Flow SecurityScheme_Flow `pb:"varint,5,opt,name=flow,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Flow" json:"flow,omitempty"` // The authorization URL to be used for this flow. This SHOULD be in // the form of a URL. // Valid for oauth2/implicit and oauth2/accessCode. - AuthorizationUrl string `protobuf:"bytes,6,opt,name=authorization_url,json=authorizationUrl,proto3" json:"authorization_url,omitempty"` + AuthorizationUrl string `pb:"bytes,6,opt,name=authorization_url,json=authorizationUrl,proto3" json:"authorization_url,omitempty"` // The token URL to be used for this flow. This SHOULD be in the // form of a URL. // Valid for oauth2/password, oauth2/application and oauth2/accessCode. - TokenUrl string `protobuf:"bytes,7,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"` + TokenUrl string `pb:"bytes,7,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"` // The available scopes for the OAuth2 security scheme. // Valid for oauth2. - Scopes *Scopes `protobuf:"bytes,8,opt,name=scopes,proto3" json:"scopes,omitempty"` + Scopes *Scopes `pb:"bytes,8,opt,name=scopes,proto3" json:"scopes,omitempty"` // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. // See: https://swagger.io/docs/specification/2-0/swagger-extensions/ - Extensions map[string]*structpb.Value `protobuf:"bytes,9,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Extensions map[string]*structpb.Value `pb:"bytes,9,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *SecurityScheme) Reset() { @@ -2152,7 +2152,7 @@ type SecurityRequirement struct { // the Security Definitions. If the security scheme is of type "oauth2", // then the value is a list of scope names required for the execution. // For other security scheme types, the array MUST be empty. - SecurityRequirement map[string]*SecurityRequirement_SecurityRequirementValue `protobuf:"bytes,1,rep,name=security_requirement,json=securityRequirement,proto3" json:"security_requirement,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + SecurityRequirement map[string]*SecurityRequirement_SecurityRequirementValue `pb:"bytes,1,rep,name=security_requirement,json=securityRequirement,proto3" json:"security_requirement,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *SecurityRequirement) Reset() { @@ -2206,7 +2206,7 @@ type Scopes struct { // Maps between a name of a scope to a short description of it (as the value // of the property). - Scope map[string]string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Scope map[string]string `pb:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Scopes) Reset() { @@ -2259,7 +2259,7 @@ type JSONSchema_FieldConfiguration struct { // be used as the complete parameter name when this field is used as a path // parameter. Use this to avoid having auto generated path parameter names // for overlapping paths. - PathParamName string `protobuf:"bytes,47,opt,name=path_param_name,json=pathParamName,proto3" json:"path_param_name,omitempty"` + PathParamName string `pb:"bytes,47,opt,name=path_param_name,json=pathParamName,proto3" json:"path_param_name,omitempty"` } func (x *JSONSchema_FieldConfiguration) Reset() { @@ -2309,7 +2309,7 @@ type SecurityRequirement_SecurityRequirementValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Scope []string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty"` + Scope []string `pb:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty"` } func (x *SecurityRequirement_SecurityRequirementValue) Reset() { @@ -2909,7 +2909,7 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_goTypes = []interface{}{ (*SecurityRequirement_SecurityRequirementValue)(nil), // 36: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue nil, // 37: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry nil, // 38: grpc.gateway.protoc_gen_openapiv2.options.Scopes.ScopeEntry - (*structpb.Value)(nil), // 39: google.protobuf.Value + (*structpb.Value)(nil), // 39: google.pb.Value } var file_protoc_gen_openapiv2_options_openapiv2_proto_depIdxs = []int32{ 12, // 0: grpc.gateway.protoc_gen_openapiv2.options.Swagger.info:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Info @@ -2951,16 +2951,16 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_depIdxs = []int32{ 37, // 36: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.security_requirement:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry 38, // 37: grpc.gateway.protoc_gen_openapiv2.options.Scopes.scope:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Scopes.ScopeEntry 11, // 38: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ResponsesEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response - 39, // 39: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ExtensionsEntry.value:type_name -> google.protobuf.Value + 39, // 39: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ExtensionsEntry.value:type_name -> google.pb.Value 11, // 40: grpc.gateway.protoc_gen_openapiv2.options.Operation.ResponsesEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response - 39, // 41: grpc.gateway.protoc_gen_openapiv2.options.Operation.ExtensionsEntry.value:type_name -> google.protobuf.Value + 39, // 41: grpc.gateway.protoc_gen_openapiv2.options.Operation.ExtensionsEntry.value:type_name -> google.pb.Value 10, // 42: grpc.gateway.protoc_gen_openapiv2.options.Response.HeadersEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Header - 39, // 43: grpc.gateway.protoc_gen_openapiv2.options.Response.ExtensionsEntry.value:type_name -> google.protobuf.Value - 39, // 44: grpc.gateway.protoc_gen_openapiv2.options.Info.ExtensionsEntry.value:type_name -> google.protobuf.Value - 39, // 45: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.ExtensionsEntry.value:type_name -> google.protobuf.Value - 39, // 46: grpc.gateway.protoc_gen_openapiv2.options.Tag.ExtensionsEntry.value:type_name -> google.protobuf.Value + 39, // 43: grpc.gateway.protoc_gen_openapiv2.options.Response.ExtensionsEntry.value:type_name -> google.pb.Value + 39, // 44: grpc.gateway.protoc_gen_openapiv2.options.Info.ExtensionsEntry.value:type_name -> google.pb.Value + 39, // 45: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.ExtensionsEntry.value:type_name -> google.pb.Value + 39, // 46: grpc.gateway.protoc_gen_openapiv2.options.Tag.ExtensionsEntry.value:type_name -> google.pb.Value 20, // 47: grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions.SecurityEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme - 39, // 48: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.ExtensionsEntry.value:type_name -> google.protobuf.Value + 39, // 48: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.ExtensionsEntry.value:type_name -> google.pb.Value 36, // 49: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue 50, // [50:50] is the sub-list for method output_type 50, // [50:50] is the sub-list for method input_type diff --git a/proto/protoc-gen-openapiv2/options/openapiv2.proto b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.proto similarity index 100% rename from proto/protoc-gen-openapiv2/options/openapiv2.proto rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.proto diff --git a/proto/protoc-gen-openapiv2/options/openapiv2.swagger.json b/internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.swagger.json similarity index 100% rename from proto/protoc-gen-openapiv2/options/openapiv2.swagger.json rename to internal/delivery/grpc/proto/protoc-gen-openapiv2/options/openapiv2.swagger.json diff --git a/proto/rpc_create_user.proto b/internal/delivery/grpc/proto/rpc_create_user.proto similarity index 100% rename from proto/rpc_create_user.proto rename to internal/delivery/grpc/proto/rpc_create_user.proto diff --git a/proto/rpc_login_user.proto b/internal/delivery/grpc/proto/rpc_login_user.proto similarity index 100% rename from proto/rpc_login_user.proto rename to internal/delivery/grpc/proto/rpc_login_user.proto diff --git a/proto/service_simple_bank.proto b/internal/delivery/grpc/proto/service_simple_bank.proto similarity index 100% rename from proto/service_simple_bank.proto rename to internal/delivery/grpc/proto/service_simple_bank.proto diff --git a/proto/user.proto b/internal/delivery/grpc/proto/user.proto similarity index 100% rename from proto/user.proto rename to internal/delivery/grpc/proto/user.proto diff --git a/api/account.go b/internal/delivery/http/account.go similarity index 76% rename from api/account.go rename to internal/delivery/http/account.go index f2c8d53..7492052 100644 --- a/api/account.go +++ b/internal/delivery/http/account.go @@ -1,13 +1,13 @@ -package api +package http import ( "database/sql" "errors" - "github.com/cukhoaimon/SimpleBank/token" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/token" "github.com/lib/pq" "net/http" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" "github.com/gin-gonic/gin" ) @@ -16,7 +16,7 @@ type createAccountRequest struct { Currency string `json:"currency" binding:"required,currency"` } -func (server *Server) createAccount(ctx *gin.Context) { +func (handler *Handler) createAccount(ctx *gin.Context) { var req createAccountRequest if err := ctx.ShouldBindJSON(&req); err != nil { @@ -24,14 +24,14 @@ func (server *Server) createAccount(ctx *gin.Context) { return } - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + authPayload := ctx.MustGet(AuthorizationPayloadKey).(*token.Payload) arg := db.CreateAccountParams{ Owner: authPayload.Username, Currency: req.Currency, Balance: 0, } - account, err := server.store.CreateAccount(ctx, arg) + account, err := handler.Store.CreateAccount(ctx, arg) if err != nil { var pqErr *pq.Error if errors.As(err, &pqErr) { @@ -53,7 +53,7 @@ type getAccountRequest struct { ID int64 `uri:"id" binding:"required,min=1"` } -func (server *Server) getAccount(ctx *gin.Context) { +func (handler *Handler) getAccount(ctx *gin.Context) { var req getAccountRequest if err := ctx.ShouldBindUri(&req); err != nil { @@ -61,7 +61,7 @@ func (server *Server) getAccount(ctx *gin.Context) { return } - account, err := server.store.GetAccount(ctx, req.ID) + account, err := handler.Store.GetAccount(ctx, req.ID) if err != nil { if errors.Is(err, sql.ErrNoRows) { ctx.JSON(http.StatusNotFound, errorResponse(err)) @@ -72,7 +72,7 @@ func (server *Server) getAccount(ctx *gin.Context) { return } - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + authPayload := ctx.MustGet(AuthorizationPayloadKey).(*token.Payload) if account.Owner != authPayload.Username { err := errors.New("this account does not belong to the authenticated user") ctx.JSON(http.StatusUnauthorized, errorResponse(err)) @@ -88,7 +88,7 @@ type listAccountRequest struct { PageSize int32 `form:"page_size" binding:"required,min=5,max=10"` } -func (server *Server) listAccount(ctx *gin.Context) { +func (handler *Handler) listAccount(ctx *gin.Context) { var req listAccountRequest if err := ctx.ShouldBindQuery(&req); err != nil { @@ -96,14 +96,14 @@ func (server *Server) listAccount(ctx *gin.Context) { return } - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + authPayload := ctx.MustGet(AuthorizationPayloadKey).(*token.Payload) arg := db.ListAccountsParams{ Owner: authPayload.Username, Limit: req.PageSize, Offset: (req.PageID - 1) * req.PageSize, } - account, err := server.store.ListAccounts(ctx, arg) + account, err := handler.Store.ListAccounts(ctx, arg) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return diff --git a/api/account_test.go b/internal/delivery/http/account_test.go similarity index 93% rename from api/account_test.go rename to internal/delivery/http/account_test.go index 5a7adab..3311ce5 100644 --- a/api/account_test.go +++ b/internal/delivery/http/account_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "bytes" @@ -11,8 +11,8 @@ import ( "testing" "time" - mockdb "github.com/cukhoaimon/SimpleBank/db/mock" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" + mockdb "github.com/cukhoaimon/SimpleBank/internal/delivery/http/mock" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" "github.com/cukhoaimon/SimpleBank/utils" "github.com/gin-gonic/gin" "github.com/golang/mock/gomock" @@ -95,7 +95,7 @@ func TestServer_getAccount(t *testing.T) { tc.buildStubs(store) // start test server and send request - server := newTestServer(t, store) + handler := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := fmt.Sprintf("/api/v1/account/%d", tc.accountID) @@ -104,8 +104,8 @@ func TestServer_getAccount(t *testing.T) { request, err := http.NewRequest(http.MethodGet, url, nil) require.Nil(t, err) - addAuthorization(t, request, server.tokenMaker, authorizationTypeBearer, user.Username, time.Minute) - server.router.ServeHTTP(recorder, request) + addAuthorization(t, request, handler.TokenMaker, AuthorizationTypeBearer, user.Username, time.Minute) + handler.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) }) @@ -196,7 +196,7 @@ func TestServer_createAccount(t *testing.T) { tc.buildStubs(store) // start test server and send request - server := newTestServer(t, store) + server := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := "/api/v1/account" @@ -208,9 +208,9 @@ func TestServer_createAccount(t *testing.T) { request, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) require.Nil(t, err) - addAuthorization(t, request, server.tokenMaker, authorizationTypeBearer, arg.Owner, time.Minute) + addAuthorization(t, request, server.TokenMaker, AuthorizationTypeBearer, arg.Owner, time.Minute) - server.router.ServeHTTP(recorder, request) + server.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) }) @@ -320,7 +320,7 @@ func TestServer_listAccount(t *testing.T) { tc.buildStubs(store) // start test server and send request - server := newTestServer(t, store) + server := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := fmt.Sprintf("/api/v1/account?page_id=%d&page_size=%d", tc.query.PageID, tc.query.PageSize) @@ -328,9 +328,9 @@ func TestServer_listAccount(t *testing.T) { // send request request, err := http.NewRequest(http.MethodGet, url, nil) require.Nil(t, err) - addAuthorization(t, request, server.tokenMaker, authorizationTypeBearer, user.Username, time.Minute) + addAuthorization(t, request, server.TokenMaker, AuthorizationTypeBearer, user.Username, time.Minute) - server.router.ServeHTTP(recorder, request) + server.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) }) diff --git a/internal/delivery/http/error.go b/internal/delivery/http/error.go new file mode 100644 index 0000000..c6d087d --- /dev/null +++ b/internal/delivery/http/error.go @@ -0,0 +1,7 @@ +package http + +import "github.com/gin-gonic/gin" + +func errorResponse(err error) gin.H { + return gin.H{"error": err.Error()} +} diff --git a/internal/delivery/http/handler.go b/internal/delivery/http/handler.go new file mode 100644 index 0000000..0b3645f --- /dev/null +++ b/internal/delivery/http/handler.go @@ -0,0 +1,40 @@ +package http + +import ( + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/token" + "github.com/cukhoaimon/SimpleBank/utils" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" + "github.com/go-playground/validator/v10" +) + +type Handler struct { + Store db.Store + Config utils.Config + TokenMaker token.Maker + Router *gin.Engine +} + +func NewHandler(store db.Store, config utils.Config) (*Handler, error) { + maker, err := token.NewPasetoMaker(config.TokenSymmetricKey) + if err != nil { + return nil, err + } + + handler := &Handler{ + Store: store, + TokenMaker: maker, + Config: config, + } + + if v, ok := binding.Validator.Engine().(*validator.Validate); ok { + err := v.RegisterValidation("currency", validCurrency) + if err != nil { + return nil, err + } + } + + handler.SetupRouter() + return handler, nil +} diff --git a/internal/delivery/http/main_test.go b/internal/delivery/http/main_test.go new file mode 100644 index 0000000..26b7694 --- /dev/null +++ b/internal/delivery/http/main_test.go @@ -0,0 +1,50 @@ +package http + +import ( + "fmt" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/token" + "github.com/cukhoaimon/SimpleBank/utils" + "github.com/stretchr/testify/require" + "os" + "testing" + "time" + + "github.com/gin-gonic/gin" + "net/http" +) + +func NewTestHandler(t *testing.T, store db.Store) *Handler { + config := utils.Config{ + TokenDuration: 15 * time.Minute, + TokenSymmetricKey: utils.RandomString(32), + } + + handler, err := NewHandler(store, config) + require.Nil(t, err) + + return handler +} + +func TestMain(m *testing.M) { + gin.SetMode(gin.TestMode) + + os.Exit(m.Run()) +} + +func addAuthorization( + t *testing.T, + request *http.Request, + tokenMaker token.Maker, + authorizationType string, + username string, + duration time.Duration, +) { + accessToken, payload, err := tokenMaker.CreateToken(username, duration) + require.Nil(t, err) + require.NotEmpty(t, payload) + require.NotEmpty(t, accessToken) + + authorizationHeader := fmt.Sprintf("%s %s", authorizationType, accessToken) + request.Header.Set(AuthorizationHeaderKey, authorizationHeader) +} diff --git a/api/middleware.go b/internal/delivery/http/middleware.go similarity index 58% rename from api/middleware.go rename to internal/delivery/http/middleware.go index bd9fe10..6658eaa 100644 --- a/api/middleware.go +++ b/internal/delivery/http/middleware.go @@ -1,41 +1,41 @@ -package api +package http import ( "errors" "fmt" - "github.com/cukhoaimon/SimpleBank/token" + "github.com/cukhoaimon/SimpleBank/pkg/token" "github.com/gin-gonic/gin" "net/http" "strings" ) const ( - authorizationHeaderKey = "authorization" - authorizationTypeBearer = "bearer" - authorizationPayloadKey = "authorization_payload" + AuthorizationHeaderKey = "authorization" + AuthorizationTypeBearer = "bearer" + AuthorizationPayloadKey = "authorization_payload" ) var ( - errAuthHeaderNotProvided = errors.New("authorization header is not provided") - errAuthHeaderInvalidFormat = errors.New("invalid authorization header format") + ErrAuthHeaderNotProvided = errors.New("authorization header is not provided") + ErrAuthHeaderInvalidFormat = errors.New("invalid authorization header format") ) -func authMiddleware(tokenMaker token.Maker) gin.HandlerFunc { +func AuthMiddleware(tokenMaker token.Maker) gin.HandlerFunc { return func(ctx *gin.Context) { - authorizationHeader := ctx.GetHeader(authorizationHeaderKey) + authorizationHeader := ctx.GetHeader(AuthorizationHeaderKey) if len(authorizationHeader) == 0 { - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(errAuthHeaderNotProvided)) + ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(ErrAuthHeaderNotProvided)) return } fields := strings.Fields(authorizationHeader) if len(fields) < 2 { - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(errAuthHeaderInvalidFormat)) + ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(ErrAuthHeaderInvalidFormat)) return } authorizationType := strings.ToLower(fields[0]) - if authorizationType != authorizationTypeBearer { + if authorizationType != AuthorizationTypeBearer { err := fmt.Errorf("authorization type %s is not supported", authorizationType) ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err)) return @@ -48,7 +48,7 @@ func authMiddleware(tokenMaker token.Maker) gin.HandlerFunc { return } - ctx.Set(authorizationPayloadKey, payload) + ctx.Set(AuthorizationPayloadKey, payload) ctx.Next() } } diff --git a/api/middleware_test.go b/internal/delivery/http/middleware_test.go similarity index 74% rename from api/middleware_test.go rename to internal/delivery/http/middleware_test.go index 444e405..698f80a 100644 --- a/api/middleware_test.go +++ b/internal/delivery/http/middleware_test.go @@ -1,8 +1,7 @@ -package api +package http import ( - "fmt" - "github.com/cukhoaimon/SimpleBank/token" + "github.com/cukhoaimon/SimpleBank/pkg/token" "github.com/cukhoaimon/SimpleBank/utils" "github.com/gin-gonic/gin" "github.com/stretchr/testify/require" @@ -12,23 +11,6 @@ import ( "time" ) -func addAuthorization( - t *testing.T, - request *http.Request, - tokenMaker token.Maker, - authorizationType string, - username string, - duration time.Duration, -) { - accessToken, payload, err := tokenMaker.CreateToken(username, duration) - require.Nil(t, err) - require.NotEmpty(t, payload) - require.NotEmpty(t, accessToken) - - authorizationHeader := fmt.Sprintf("%s %s", authorizationType, accessToken) - request.Header.Set(authorizationHeaderKey, authorizationHeader) -} - func Test_authMiddleware(t *testing.T) { tests := []struct { name string @@ -38,7 +20,7 @@ func Test_authMiddleware(t *testing.T) { { name: "200 OK", setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, "user", time.Minute) + addAuthorization(t, request, tokenMaker, AuthorizationTypeBearer, "user", time.Minute) }, checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { require.Equal(t, http.StatusOK, recorder.Code) @@ -76,7 +58,7 @@ func Test_authMiddleware(t *testing.T) { // provide JWT token, but server is using Paseto token => invalid token jwtMaker, err := token.NewJWTMaker(utils.RandomString(32)) require.Nil(t, err) - addAuthorization(t, request, jwtMaker, authorizationTypeBearer, "user", time.Minute) + addAuthorization(t, request, jwtMaker, AuthorizationTypeBearer, "user", time.Minute) }, checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { require.Equal(t, http.StatusUnauthorized, recorder.Code) @@ -85,11 +67,25 @@ func Test_authMiddleware(t *testing.T) { } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - server := newTestServer(t, nil) + config := utils.Config{ + TokenDuration: 15 * time.Minute, + TokenSymmetricKey: utils.RandomString(32), + } + + pasetoMaker, err := token.NewPasetoMaker(config.TokenSymmetricKey) + require.Nil(t, err) + + handler := &Handler{ + Store: nil, + Config: config, + TokenMaker: pasetoMaker, + } + authPath := "/auth" - server.router.GET( + handler.Router = gin.Default() + handler.Router.GET( authPath, - authMiddleware(server.tokenMaker), + AuthMiddleware(handler.TokenMaker), func(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{}) }, @@ -99,8 +95,8 @@ func Test_authMiddleware(t *testing.T) { request, err := http.NewRequest(http.MethodGet, authPath, nil) require.Nil(t, err) - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) + tc.setupAuth(t, request, handler.TokenMaker) + handler.Router.ServeHTTP(recorder, request) tc.checkResponse(t, recorder) }) } diff --git a/db/mock/store.go b/internal/delivery/http/mock/store.go similarity index 82% rename from db/mock/store.go rename to internal/delivery/http/mock/store.go index dcc4e9f..fb51988 100644 --- a/db/mock/store.go +++ b/internal/delivery/http/mock/store.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/cukhoaimon/SimpleBank/db/sqlc (interfaces: Store) +// Source: github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc (interfaces: Store) // Package mockdb is a generated GoMock package. package mockdb @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" + usecase "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" gomock "github.com/golang/mock/gomock" uuid "github.com/google/uuid" ) @@ -37,10 +37,10 @@ func (m *MockStore) EXPECT() *MockStoreMockRecorder { } // AddAccountBalance mocks base method. -func (m *MockStore) AddAccountBalance(arg0 context.Context, arg1 db.AddAccountBalanceParams) (db.Account, error) { +func (m *MockStore) AddAccountBalance(arg0 context.Context, arg1 usecase.AddAccountBalanceParams) (usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddAccountBalance", arg0, arg1) - ret0, _ := ret[0].(db.Account) + ret0, _ := ret[0].(usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -52,10 +52,10 @@ func (mr *MockStoreMockRecorder) AddAccountBalance(arg0, arg1 interface{}) *gomo } // CreateAccount mocks base method. -func (m *MockStore) CreateAccount(arg0 context.Context, arg1 db.CreateAccountParams) (db.Account, error) { +func (m *MockStore) CreateAccount(arg0 context.Context, arg1 usecase.CreateAccountParams) (usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAccount", arg0, arg1) - ret0, _ := ret[0].(db.Account) + ret0, _ := ret[0].(usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -67,10 +67,10 @@ func (mr *MockStoreMockRecorder) CreateAccount(arg0, arg1 interface{}) *gomock.C } // CreateEntry mocks base method. -func (m *MockStore) CreateEntry(arg0 context.Context, arg1 db.CreateEntryParams) (db.Entry, error) { +func (m *MockStore) CreateEntry(arg0 context.Context, arg1 usecase.CreateEntryParams) (usecase.Entry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateEntry", arg0, arg1) - ret0, _ := ret[0].(db.Entry) + ret0, _ := ret[0].(usecase.Entry) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -82,10 +82,10 @@ func (mr *MockStoreMockRecorder) CreateEntry(arg0, arg1 interface{}) *gomock.Cal } // CreateSession mocks base method. -func (m *MockStore) CreateSession(arg0 context.Context, arg1 db.CreateSessionParams) (db.Session, error) { +func (m *MockStore) CreateSession(arg0 context.Context, arg1 usecase.CreateSessionParams) (usecase.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", arg0, arg1) - ret0, _ := ret[0].(db.Session) + ret0, _ := ret[0].(usecase.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -97,10 +97,10 @@ func (mr *MockStoreMockRecorder) CreateSession(arg0, arg1 interface{}) *gomock.C } // CreateTransfer mocks base method. -func (m *MockStore) CreateTransfer(arg0 context.Context, arg1 db.CreateTransferParams) (db.Transfer, error) { +func (m *MockStore) CreateTransfer(arg0 context.Context, arg1 usecase.CreateTransferParams) (usecase.Transfer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateTransfer", arg0, arg1) - ret0, _ := ret[0].(db.Transfer) + ret0, _ := ret[0].(usecase.Transfer) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -112,10 +112,10 @@ func (mr *MockStoreMockRecorder) CreateTransfer(arg0, arg1 interface{}) *gomock. } // CreateUser mocks base method. -func (m *MockStore) CreateUser(arg0 context.Context, arg1 db.CreateUserParams) (db.User, error) { +func (m *MockStore) CreateUser(arg0 context.Context, arg1 usecase.CreateUserParams) (usecase.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateUser", arg0, arg1) - ret0, _ := ret[0].(db.User) + ret0, _ := ret[0].(usecase.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -141,10 +141,10 @@ func (mr *MockStoreMockRecorder) DeleteAccount(arg0, arg1 interface{}) *gomock.C } // GetAccount mocks base method. -func (m *MockStore) GetAccount(arg0 context.Context, arg1 int64) (db.Account, error) { +func (m *MockStore) GetAccount(arg0 context.Context, arg1 int64) (usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAccount", arg0, arg1) - ret0, _ := ret[0].(db.Account) + ret0, _ := ret[0].(usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -156,10 +156,10 @@ func (mr *MockStoreMockRecorder) GetAccount(arg0, arg1 interface{}) *gomock.Call } // GetAccountForUpdate mocks base method. -func (m *MockStore) GetAccountForUpdate(arg0 context.Context, arg1 int64) (db.Account, error) { +func (m *MockStore) GetAccountForUpdate(arg0 context.Context, arg1 int64) (usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAccountForUpdate", arg0, arg1) - ret0, _ := ret[0].(db.Account) + ret0, _ := ret[0].(usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -171,10 +171,10 @@ func (mr *MockStoreMockRecorder) GetAccountForUpdate(arg0, arg1 interface{}) *go } // GetEntry mocks base method. -func (m *MockStore) GetEntry(arg0 context.Context, arg1 int64) (db.Entry, error) { +func (m *MockStore) GetEntry(arg0 context.Context, arg1 int64) (usecase.Entry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetEntry", arg0, arg1) - ret0, _ := ret[0].(db.Entry) + ret0, _ := ret[0].(usecase.Entry) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -186,10 +186,10 @@ func (mr *MockStoreMockRecorder) GetEntry(arg0, arg1 interface{}) *gomock.Call { } // GetSession mocks base method. -func (m *MockStore) GetSession(arg0 context.Context, arg1 uuid.UUID) (db.Session, error) { +func (m *MockStore) GetSession(arg0 context.Context, arg1 uuid.UUID) (usecase.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", arg0, arg1) - ret0, _ := ret[0].(db.Session) + ret0, _ := ret[0].(usecase.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -201,10 +201,10 @@ func (mr *MockStoreMockRecorder) GetSession(arg0, arg1 interface{}) *gomock.Call } // GetTransfer mocks base method. -func (m *MockStore) GetTransfer(arg0 context.Context, arg1 int64) (db.Transfer, error) { +func (m *MockStore) GetTransfer(arg0 context.Context, arg1 int64) (usecase.Transfer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTransfer", arg0, arg1) - ret0, _ := ret[0].(db.Transfer) + ret0, _ := ret[0].(usecase.Transfer) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -216,10 +216,10 @@ func (mr *MockStoreMockRecorder) GetTransfer(arg0, arg1 interface{}) *gomock.Cal } // GetUser mocks base method. -func (m *MockStore) GetUser(arg0 context.Context, arg1 string) (db.User, error) { +func (m *MockStore) GetUser(arg0 context.Context, arg1 string) (usecase.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUser", arg0, arg1) - ret0, _ := ret[0].(db.User) + ret0, _ := ret[0].(usecase.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -231,10 +231,10 @@ func (mr *MockStoreMockRecorder) GetUser(arg0, arg1 interface{}) *gomock.Call { } // ListAccounts mocks base method. -func (m *MockStore) ListAccounts(arg0 context.Context, arg1 db.ListAccountsParams) ([]db.Account, error) { +func (m *MockStore) ListAccounts(arg0 context.Context, arg1 usecase.ListAccountsParams) ([]usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListAccounts", arg0, arg1) - ret0, _ := ret[0].([]db.Account) + ret0, _ := ret[0].([]usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -246,10 +246,10 @@ func (mr *MockStoreMockRecorder) ListAccounts(arg0, arg1 interface{}) *gomock.Ca } // ListEntries mocks base method. -func (m *MockStore) ListEntries(arg0 context.Context, arg1 db.ListEntriesParams) ([]db.Entry, error) { +func (m *MockStore) ListEntries(arg0 context.Context, arg1 usecase.ListEntriesParams) ([]usecase.Entry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListEntries", arg0, arg1) - ret0, _ := ret[0].([]db.Entry) + ret0, _ := ret[0].([]usecase.Entry) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -261,10 +261,10 @@ func (mr *MockStoreMockRecorder) ListEntries(arg0, arg1 interface{}) *gomock.Cal } // ListTransfers mocks base method. -func (m *MockStore) ListTransfers(arg0 context.Context, arg1 db.ListTransfersParams) ([]db.Transfer, error) { +func (m *MockStore) ListTransfers(arg0 context.Context, arg1 usecase.ListTransfersParams) ([]usecase.Transfer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListTransfers", arg0, arg1) - ret0, _ := ret[0].([]db.Transfer) + ret0, _ := ret[0].([]usecase.Transfer) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -276,10 +276,10 @@ func (mr *MockStoreMockRecorder) ListTransfers(arg0, arg1 interface{}) *gomock.C } // TransferTxAccount mocks base method. -func (m *MockStore) TransferTxAccount(arg0 context.Context, arg1 db.TransferTxParams) (db.TransferTxResult, error) { +func (m *MockStore) TransferTxAccount(arg0 context.Context, arg1 usecase.TransferTxParams) (usecase.TransferTxResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TransferTxAccount", arg0, arg1) - ret0, _ := ret[0].(db.TransferTxResult) + ret0, _ := ret[0].(usecase.TransferTxResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -291,10 +291,10 @@ func (mr *MockStoreMockRecorder) TransferTxAccount(arg0, arg1 interface{}) *gomo } // UpdateAccount mocks base method. -func (m *MockStore) UpdateAccount(arg0 context.Context, arg1 db.UpdateAccountParams) (db.Account, error) { +func (m *MockStore) UpdateAccount(arg0 context.Context, arg1 usecase.UpdateAccountParams) (usecase.Account, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAccount", arg0, arg1) - ret0, _ := ret[0].(db.Account) + ret0, _ := ret[0].(usecase.Account) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/internal/delivery/http/router.go b/internal/delivery/http/router.go new file mode 100644 index 0000000..12bc5c2 --- /dev/null +++ b/internal/delivery/http/router.go @@ -0,0 +1,22 @@ +package http + +import ( + "github.com/gin-gonic/gin" +) + +func (handler *Handler) SetupRouter() { + router := gin.Default() + router.POST("/api/v1/user", handler.createUser) + router.POST("/api/v1/user/login", handler.loginUser) + router.POST("/api/v1/user/token/renew_access", handler.renewAccessTokenUser) + + authRoutes := router.Group("/").Use(AuthMiddleware(handler.TokenMaker)) + + authRoutes.GET("/api/v1/account", handler.listAccount) + authRoutes.GET("/api/v1/account/:id", handler.getAccount) + authRoutes.POST("/api/v1/account", handler.createAccount) + + authRoutes.POST("/api/v1/transfer", handler.createTransfer) + + handler.Router = router +} diff --git a/api/token.go b/internal/delivery/http/token.go similarity index 83% rename from api/token.go rename to internal/delivery/http/token.go index b521b3e..6f5f651 100644 --- a/api/token.go +++ b/internal/delivery/http/token.go @@ -1,4 +1,4 @@ -package api +package http import ( "database/sql" @@ -17,7 +17,7 @@ type renewAccessTokenResponse struct { AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` } -func (server *Server) renewAccessTokenUser(ctx *gin.Context) { +func (handler *Handler) renewAccessTokenUser(ctx *gin.Context) { var req renewAccessTokenRequest if err := ctx.ShouldBindJSON(&req); err != nil { @@ -25,9 +25,9 @@ func (server *Server) renewAccessTokenUser(ctx *gin.Context) { return } - refreshPayload, err := server.tokenMaker.VerifyToken(req.RefreshToken) + refreshPayload, err := handler.TokenMaker.VerifyToken(req.RefreshToken) - session, err := server.store.GetSession(ctx, refreshPayload.Id) + session, err := handler.Store.GetSession(ctx, refreshPayload.Id) if err != nil { if errors.Is(err, sql.ErrNoRows) { ctx.JSON(http.StatusNotFound, errorResponse(err)) @@ -62,9 +62,9 @@ func (server *Server) renewAccessTokenUser(ctx *gin.Context) { return } - token, accessTokenPayload, err := server.tokenMaker.CreateToken( + token, accessTokenPayload, err := handler.TokenMaker.CreateToken( refreshPayload.Username, - server.config.TokenDuration, + handler.Config.TokenDuration, ) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) diff --git a/api/token_test.go b/internal/delivery/http/token_test.go similarity index 83% rename from api/token_test.go rename to internal/delivery/http/token_test.go index b1796d4..b2748bc 100644 --- a/api/token_test.go +++ b/internal/delivery/http/token_test.go @@ -1,7 +1,7 @@ -package api +package http import ( - mockdb "github.com/cukhoaimon/SimpleBank/db/mock" + mockdb "github.com/cukhoaimon/SimpleBank/internal/delivery/http/mock" "github.com/gin-gonic/gin" "net/http/httptest" "testing" diff --git a/api/transfer.go b/internal/delivery/http/transfer.go similarity index 68% rename from api/transfer.go rename to internal/delivery/http/transfer.go index 983e2ad..fcf08ea 100644 --- a/api/transfer.go +++ b/internal/delivery/http/transfer.go @@ -1,11 +1,11 @@ -package api +package http import ( "database/sql" "errors" "fmt" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/token" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/pkg/token" "github.com/gin-gonic/gin" "net/http" ) @@ -17,7 +17,7 @@ type transferRequest struct { Currency string `json:"currency" binding:"required,currency"` } -func (server *Server) createTransfer(ctx *gin.Context) { +func (handler *Handler) createTransfer(ctx *gin.Context) { var req transferRequest if err := ctx.ShouldBindJSON(&req); err != nil { @@ -25,15 +25,15 @@ func (server *Server) createTransfer(ctx *gin.Context) { return } - if !server.validOwner(ctx, req.FromAccountID) { + if !handler.validOwner(ctx, req.FromAccountID) { return } - if !server.validAccount(ctx, req.FromAccountID, req.Currency) { + if !handler.validAccount(ctx, req.FromAccountID, req.Currency) { return } - if !server.validAccount(ctx, req.ToAccountID, req.Currency) { + if !handler.validAccount(ctx, req.ToAccountID, req.Currency) { return } @@ -43,7 +43,7 @@ func (server *Server) createTransfer(ctx *gin.Context) { Amount: req.Amount, } - account, err := server.store.TransferTxAccount(ctx, arg) + account, err := handler.Store.TransferTxAccount(ctx, arg) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return @@ -52,8 +52,8 @@ func (server *Server) createTransfer(ctx *gin.Context) { ctx.JSON(http.StatusCreated, account) } -func (server *Server) validOwner(ctx *gin.Context, accountID int64) bool { - account, err := server.store.GetAccount(ctx, accountID) +func (handler *Handler) validOwner(ctx *gin.Context, accountID int64) bool { + account, err := handler.Store.GetAccount(ctx, accountID) if err != nil { if errors.Is(err, sql.ErrNoRows) { ctx.JSON(http.StatusNotFound, errorResponse(err)) @@ -64,7 +64,7 @@ func (server *Server) validOwner(ctx *gin.Context, accountID int64) bool { return false } - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + authPayload := ctx.MustGet(AuthorizationPayloadKey).(*token.Payload) if account.Owner != authPayload.Username { err = errors.New("from_account is not belong to the authorized user") ctx.JSON(http.StatusUnauthorized, errorResponse(err)) @@ -74,8 +74,8 @@ func (server *Server) validOwner(ctx *gin.Context, accountID int64) bool { return true } -func (server *Server) validAccount(ctx *gin.Context, accountID int64, currency string) bool { - account, err := server.store.GetAccount(ctx, accountID) +func (handler *Handler) validAccount(ctx *gin.Context, accountID int64, currency string) bool { + account, err := handler.Store.GetAccount(ctx, accountID) if err != nil { if errors.Is(err, sql.ErrNoRows) { ctx.JSON(http.StatusNotFound, errorResponse(err)) diff --git a/api/transfer_test.go b/internal/delivery/http/transfer_test.go similarity index 95% rename from api/transfer_test.go rename to internal/delivery/http/transfer_test.go index bdc32b0..19d4eba 100644 --- a/api/transfer_test.go +++ b/internal/delivery/http/transfer_test.go @@ -1,11 +1,12 @@ -package api +package http import ( "bytes" "database/sql" "encoding/json" - mockdb "github.com/cukhoaimon/SimpleBank/db/mock" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" + mockdb "github.com/cukhoaimon/SimpleBank/internal/delivery/http/mock" + + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" "github.com/cukhoaimon/SimpleBank/utils" "github.com/gin-gonic/gin" "github.com/golang/mock/gomock" @@ -269,7 +270,7 @@ func TestServer_createTransfer(t *testing.T) { tc.buildStubs(store) // start test server and send request - server := newTestServer(t, store) + handler := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := "/api/v1/transfer" @@ -281,8 +282,8 @@ func TestServer_createTransfer(t *testing.T) { request, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) require.Nil(t, err) - addAuthorization(t, request, server.tokenMaker, authorizationTypeBearer, fromAccount.Owner, time.Minute) - server.router.ServeHTTP(recorder, request) + addAuthorization(t, request, handler.TokenMaker, AuthorizationTypeBearer, fromAccount.Owner, time.Minute) + handler.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) diff --git a/api/user.go b/internal/delivery/http/user.go similarity index 84% rename from api/user.go rename to internal/delivery/http/user.go index eb8b8d5..7d655e0 100644 --- a/api/user.go +++ b/internal/delivery/http/user.go @@ -1,9 +1,9 @@ -package api +package http import ( "database/sql" "errors" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" + usecase "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" "github.com/cukhoaimon/SimpleBank/utils" "github.com/gin-gonic/gin" "github.com/google/uuid" @@ -27,7 +27,7 @@ type userResponse struct { CreatedAt time.Time `json:"created_at"` } -func (server *Server) createUser(ctx *gin.Context) { +func (handler *Handler) createUser(ctx *gin.Context) { var req createUserRequest if err := ctx.ShouldBindJSON(&req); err != nil { @@ -41,14 +41,14 @@ func (server *Server) createUser(ctx *gin.Context) { return } - arg := db.CreateUserParams{ + arg := usecase.CreateUserParams{ Username: req.Username, HashedPassword: hashedPassword, FullName: req.FullName, Email: req.Email, } - user, err := server.store.CreateUser(ctx, arg) + user, err := handler.Store.CreateUser(ctx, arg) if err != nil { var pqErr *pq.Error if errors.As(err, &pqErr) { @@ -82,7 +82,7 @@ type loginResponse struct { User userResponse `json:"user"` } -func (server *Server) loginUser(ctx *gin.Context) { +func (handler *Handler) loginUser(ctx *gin.Context) { var req loginRequest if err := ctx.ShouldBindJSON(&req); err != nil { @@ -90,7 +90,7 @@ func (server *Server) loginUser(ctx *gin.Context) { return } - user, err := server.store.GetUser(ctx, req.Username) + user, err := handler.Store.GetUser(ctx, req.Username) if err != nil { if errors.Is(err, sql.ErrNoRows) { ctx.JSON(http.StatusNotFound, errorResponse(err)) @@ -107,19 +107,19 @@ func (server *Server) loginUser(ctx *gin.Context) { return } - token, accessTokenPayload, err := server.tokenMaker.CreateToken(req.Username, server.config.TokenDuration) + token, accessTokenPayload, err := handler.TokenMaker.CreateToken(req.Username, handler.Config.TokenDuration) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } - refreshToken, refreshTokenPayload, err := server.tokenMaker.CreateToken(req.Username, server.config.RefreshTokenDuration) + refreshToken, refreshTokenPayload, err := handler.TokenMaker.CreateToken(req.Username, handler.Config.RefreshTokenDuration) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } - arg := db.CreateSessionParams{ + arg := usecase.CreateSessionParams{ ID: accessTokenPayload.Id, Username: accessTokenPayload.Username, RefreshToken: refreshToken, @@ -129,7 +129,7 @@ func (server *Server) loginUser(ctx *gin.Context) { ExpiresAt: refreshTokenPayload.ExpiredAt, } - session, err := server.store.CreateSession(ctx, arg) + session, err := handler.Store.CreateSession(ctx, arg) if err != nil { var pqErr *pq.Error if errors.As(err, &pqErr) { @@ -157,7 +157,7 @@ func (server *Server) loginUser(ctx *gin.Context) { return } -func makeUserResponse(user db.User) userResponse { +func makeUserResponse(user usecase.User) userResponse { return userResponse{ Username: user.Username, FullName: user.FullName, diff --git a/api/user_test.go b/internal/delivery/http/user_test.go similarity index 94% rename from api/user_test.go rename to internal/delivery/http/user_test.go index e32addb..1af58a3 100644 --- a/api/user_test.go +++ b/internal/delivery/http/user_test.go @@ -1,12 +1,13 @@ -package api +package http import ( "bytes" "database/sql" "encoding/json" "fmt" - mockdb "github.com/cukhoaimon/SimpleBank/db/mock" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" + mockdb "github.com/cukhoaimon/SimpleBank/internal/delivery/http/mock" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/utils" "github.com/gin-gonic/gin" "github.com/golang/mock/gomock" @@ -138,8 +139,8 @@ func TestServer_createUser(t *testing.T) { // build stubs tc.buildStubs(store) - // start test server and send request - server := newTestServer(t, store) + // start test handler and send request + handler := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := "/api/v1/user" @@ -151,7 +152,7 @@ func TestServer_createUser(t *testing.T) { request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) require.Nil(t, err) - server.router.ServeHTTP(recorder, request) + handler.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) @@ -231,7 +232,7 @@ func TestServer_loginUser(t *testing.T) { }, }, { - name: "500 Internal server error", + name: "500 Internal handler error", body: gin.H{ "username": user.Username, "password": password, @@ -275,8 +276,8 @@ func TestServer_loginUser(t *testing.T) { // build stubs tc.buildStubs(store) - // start test server and send request - server := newTestServer(t, store) + // start test handler and send request + handler := NewTestHandler(t, store) recorder := httptest.NewRecorder() url := "/api/v1/user/login" @@ -288,7 +289,7 @@ func TestServer_loginUser(t *testing.T) { request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) require.Nil(t, err) - server.router.ServeHTTP(recorder, request) + handler.Router.ServeHTTP(recorder, request) // check response tc.checkResponse(t, recorder) diff --git a/api/validator.go b/internal/delivery/http/validator.go similarity index 96% rename from api/validator.go rename to internal/delivery/http/validator.go index 737c676..d6f3fda 100644 --- a/api/validator.go +++ b/internal/delivery/http/validator.go @@ -1,4 +1,4 @@ -package api +package http import ( "github.com/cukhoaimon/SimpleBank/utils" diff --git a/internal/domain/domain.go b/internal/domain/domain.go new file mode 100644 index 0000000..e570250 --- /dev/null +++ b/internal/domain/domain.go @@ -0,0 +1,52 @@ +package domain + +import ( + "time" + + "github.com/google/uuid" +) + +type Account struct { + ID int64 `json:"id"` + Owner string `json:"owner"` + Balance int64 `json:"balance"` + Currency string `json:"currency"` + CreatedAt time.Time `json:"created_at"` +} + +type Entry struct { + ID int64 `json:"id"` + AccountID int64 `json:"account_id"` + // can be negative or positive + Amount int64 `json:"amount"` + CreatedAt time.Time `json:"created_at"` +} + +type Session struct { + ID uuid.UUID `json:"id"` + Username string `json:"username"` + RefreshToken string `json:"refresh_token"` + UserAgent string `json:"user_agent"` + ClientIp string `json:"client_ip"` + IsBlocked bool `json:"is_blocked"` + ExpiresAt time.Time `json:"expires_at"` + CreatedAt time.Time `json:"created_at"` +} + +type Transfer struct { + ID int64 `json:"id"` + FromAccountID int64 `json:"from_account_id"` + ToAccountID int64 `json:"to_account_id"` + // must be positive + Amount int64 `json:"amount"` + CreatedAt time.Time `json:"created_at"` +} + +type User struct { + Username string `json:"username"` + HashedPassword string `json:"hashed_password"` + FullName string `json:"full_name"` + Email string `json:"email"` + PasswordChangedAt time.Time `json:"password_changed_at"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/db/query/account.sql b/internal/usecase/query/account.sql similarity index 100% rename from db/query/account.sql rename to internal/usecase/query/account.sql diff --git a/db/query/entry.sql b/internal/usecase/query/entry.sql similarity index 100% rename from db/query/entry.sql rename to internal/usecase/query/entry.sql diff --git a/db/query/session.sql b/internal/usecase/query/session.sql similarity index 100% rename from db/query/session.sql rename to internal/usecase/query/session.sql diff --git a/db/query/transfer.sql b/internal/usecase/query/transfer.sql similarity index 100% rename from db/query/transfer.sql rename to internal/usecase/query/transfer.sql diff --git a/db/query/user.sql b/internal/usecase/query/user.sql similarity index 100% rename from db/query/user.sql rename to internal/usecase/query/user.sql diff --git a/db/sqlc/account.sql.go b/internal/usecase/sqlc/account.sql.go similarity index 99% rename from db/sqlc/account.sql.go rename to internal/usecase/sqlc/account.sql.go index 4f8cb64..186d24b 100644 --- a/db/sqlc/account.sql.go +++ b/internal/usecase/sqlc/account.sql.go @@ -3,7 +3,7 @@ // sqlc v1.25.0 // source: account.sql -package db +package usecase import ( "context" diff --git a/db/sqlc/account.sql_test.go b/internal/usecase/sqlc/account.sql_test.go similarity index 99% rename from db/sqlc/account.sql_test.go rename to internal/usecase/sqlc/account.sql_test.go index 92b6122..092706d 100644 --- a/db/sqlc/account.sql_test.go +++ b/internal/usecase/sqlc/account.sql_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" diff --git a/db/sqlc/db.go b/internal/usecase/sqlc/db.go similarity index 97% rename from db/sqlc/db.go rename to internal/usecase/sqlc/db.go index bdb151c..9b37d0d 100644 --- a/db/sqlc/db.go +++ b/internal/usecase/sqlc/db.go @@ -2,7 +2,7 @@ // versions: // sqlc v1.25.0 -package db +package usecase import ( "context" diff --git a/db/sqlc/entry.sql.go b/internal/usecase/sqlc/entry.sql.go similarity index 99% rename from db/sqlc/entry.sql.go rename to internal/usecase/sqlc/entry.sql.go index e2b229b..581fccb 100644 --- a/db/sqlc/entry.sql.go +++ b/internal/usecase/sqlc/entry.sql.go @@ -3,7 +3,7 @@ // sqlc v1.25.0 // source: entry.sql -package db +package usecase import ( "context" diff --git a/db/sqlc/entry.sql_test.go b/internal/usecase/sqlc/entry.sql_test.go similarity index 97% rename from db/sqlc/entry.sql_test.go rename to internal/usecase/sqlc/entry.sql_test.go index 47f73e7..36b5ee8 100644 --- a/db/sqlc/entry.sql_test.go +++ b/internal/usecase/sqlc/entry.sql_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" @@ -45,7 +45,7 @@ func TestQueries_GetEntry(t *testing.T) { func TestQueries_ListEntries(t *testing.T) { account := createRandomAccount(t) - entries := []Entry{} + var entries []Entry for i := 0; i < 10; i++ { entries = append(entries, createRandomEntry(t, account)) diff --git a/db/sqlc/main_test.go b/internal/usecase/sqlc/main_test.go similarity index 88% rename from db/sqlc/main_test.go rename to internal/usecase/sqlc/main_test.go index 7491a5d..399a511 100644 --- a/db/sqlc/main_test.go +++ b/internal/usecase/sqlc/main_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "database/sql" @@ -14,7 +14,7 @@ var testQuery *Queries var testDB *sql.DB func TestMain(m *testing.M) { - config, err := utils.LoadConfig("../..") + config, err := utils.LoadConfig("../../../.") if err != nil { log.Fatal("Cannot load configuration file") } diff --git a/db/sqlc/models.go b/internal/usecase/sqlc/models.go similarity index 98% rename from db/sqlc/models.go rename to internal/usecase/sqlc/models.go index 33fd055..42d4eff 100644 --- a/db/sqlc/models.go +++ b/internal/usecase/sqlc/models.go @@ -2,7 +2,7 @@ // versions: // sqlc v1.25.0 -package db +package usecase import ( "time" diff --git a/db/sqlc/querier.go b/internal/usecase/sqlc/querier.go similarity index 98% rename from db/sqlc/querier.go rename to internal/usecase/sqlc/querier.go index a933b0a..7dd0fb9 100644 --- a/db/sqlc/querier.go +++ b/internal/usecase/sqlc/querier.go @@ -2,7 +2,7 @@ // versions: // sqlc v1.25.0 -package db +package usecase import ( "context" diff --git a/db/sqlc/session.sql.go b/internal/usecase/sqlc/session.sql.go similarity index 99% rename from db/sqlc/session.sql.go rename to internal/usecase/sqlc/session.sql.go index 9a874c0..5ea6452 100644 --- a/db/sqlc/session.sql.go +++ b/internal/usecase/sqlc/session.sql.go @@ -3,7 +3,7 @@ // sqlc v1.25.0 // source: session.sql -package db +package usecase import ( "context" diff --git a/db/sqlc/store.go b/internal/usecase/sqlc/store.go similarity index 99% rename from db/sqlc/store.go rename to internal/usecase/sqlc/store.go index 683ef88..213036c 100644 --- a/db/sqlc/store.go +++ b/internal/usecase/sqlc/store.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" diff --git a/db/sqlc/store_test.go b/internal/usecase/sqlc/store_test.go similarity index 99% rename from db/sqlc/store_test.go rename to internal/usecase/sqlc/store_test.go index 14e764b..ae784a7 100644 --- a/db/sqlc/store_test.go +++ b/internal/usecase/sqlc/store_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" diff --git a/db/sqlc/transfer.sql.go b/internal/usecase/sqlc/transfer.sql.go similarity index 99% rename from db/sqlc/transfer.sql.go rename to internal/usecase/sqlc/transfer.sql.go index 6b031c1..2d2be0f 100644 --- a/db/sqlc/transfer.sql.go +++ b/internal/usecase/sqlc/transfer.sql.go @@ -3,7 +3,7 @@ // sqlc v1.25.0 // source: transfer.sql -package db +package usecase import ( "context" diff --git a/db/sqlc/transfer.sql_test.go b/internal/usecase/sqlc/transfer.sql_test.go similarity index 72% rename from db/sqlc/transfer.sql_test.go rename to internal/usecase/sqlc/transfer.sql_test.go index d3d6aff..1c74704 100644 --- a/db/sqlc/transfer.sql_test.go +++ b/internal/usecase/sqlc/transfer.sql_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" @@ -9,10 +9,10 @@ import ( "github.com/stretchr/testify/require" ) -func createRandomTransfer(t *testing.T, from_account, to_account Account) Transfer { +func createRandomTransfer(t *testing.T, fromAccount, toAccount Account) Transfer { arg := CreateTransferParams{ - FromAccountID: from_account.ID, - ToAccountID: to_account.ID, + FromAccountID: fromAccount.ID, + ToAccountID: toAccount.ID, Amount: utils.RandomMoney(), } @@ -29,16 +29,16 @@ func createRandomTransfer(t *testing.T, from_account, to_account Account) Transf } func TestQueries_CreateTransfer(t *testing.T) { - from_account := createRandomAccount(t) - to_account := createRandomAccount(t) + fromAccount := createRandomAccount(t) + toAccount := createRandomAccount(t) - createRandomTransfer(t, from_account, to_account) + createRandomTransfer(t, fromAccount, toAccount) } func TestQueries_GetTransfer(t *testing.T) { - from_account := createRandomAccount(t) - to_account := createRandomAccount(t) - want := createRandomTransfer(t, from_account, to_account) + fromAccount := createRandomAccount(t) + toAccount := createRandomAccount(t) + want := createRandomTransfer(t, fromAccount, toAccount) have, err := testQuery.GetTransfer(context.Background(), want.ID) @@ -52,19 +52,19 @@ func TestQueries_GetTransfer(t *testing.T) { } func TestQueries_ListTransfers(t *testing.T) { - from_account := createRandomAccount(t) - to_account := createRandomAccount(t) + fromAccount := createRandomAccount(t) + toAccount := createRandomAccount(t) - transfers := []Transfer{} + var transfers []Transfer for i := 0; i < 10; i++ { - transfer := createRandomTransfer(t, from_account, to_account) + transfer := createRandomTransfer(t, fromAccount, toAccount) transfers = append(transfers, transfer) } arg := ListTransfersParams{ - FromAccountID: from_account.ID, - ToAccountID: to_account.ID, + FromAccountID: fromAccount.ID, + ToAccountID: toAccount.ID, Limit: 5, Offset: 5, } diff --git a/db/sqlc/user.sql.go b/internal/usecase/sqlc/user.sql.go similarity index 98% rename from db/sqlc/user.sql.go rename to internal/usecase/sqlc/user.sql.go index 5eddaa9..9706a46 100644 --- a/db/sqlc/user.sql.go +++ b/internal/usecase/sqlc/user.sql.go @@ -3,7 +3,7 @@ // sqlc v1.25.0 // source: user.sql -package db +package usecase import ( "context" diff --git a/db/sqlc/user.sql_test.go b/internal/usecase/sqlc/user.sql_test.go similarity index 98% rename from db/sqlc/user.sql_test.go rename to internal/usecase/sqlc/user.sql_test.go index 70cabfc..ff6948e 100644 --- a/db/sqlc/user.sql_test.go +++ b/internal/usecase/sqlc/user.sql_test.go @@ -1,4 +1,4 @@ -package db +package usecase import ( "context" diff --git a/val/validator.go b/internal/usecase/val/validator.go similarity index 100% rename from val/validator.go rename to internal/usecase/val/validator.go diff --git a/main.go b/main.go deleted file mode 100644 index 5fb3042..0000000 --- a/main.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "context" - "database/sql" - "github.com/cukhoaimon/SimpleBank/api" - db "github.com/cukhoaimon/SimpleBank/db/sqlc" - "github.com/cukhoaimon/SimpleBank/gapi" - "github.com/cukhoaimon/SimpleBank/pb" - "github.com/cukhoaimon/SimpleBank/utils" - "github.com/golang-migrate/migrate/v4/database" - "github.com/golang-migrate/migrate/v4/database/postgres" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - _ "github.com/lib/pq" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" - "google.golang.org/protobuf/encoding/protojson" - "log" - "net" - "net/http" - - "github.com/golang-migrate/migrate/v4" - _ "github.com/golang-migrate/migrate/v4/database/postgres" - _ "github.com/golang-migrate/migrate/v4/source/file" - _ "github.com/golang-migrate/migrate/v4/source/github" -) - -func main() { - config, err := utils.LoadConfig(".") - if err != nil { - - log.Fatal(err.Error()) - } - - conn, err := sql.Open(config.DBDriver, config.DBSource) - if err != nil { - log.Fatal("The open connection to database process was encountered an error", err) - } - - driver, err := postgres.WithInstance(conn, &postgres.Config{}) - if err != nil { - log.Fatal("Error when create postgres driver instance: ", err) - } - - runDBMigration(config.MigrationURL, config.PostgresDB, driver) - - store := db.NewStore(conn) - - go runGatewayServer(store, config) - runGRPCServer(store, config) -} - -func runDBMigration(sourceURL string, databaseName string, databaseInstance database.Driver) { - migration, err := migrate.NewWithDatabaseInstance(sourceURL, databaseName, databaseInstance) - if err != nil { - log.Fatal("fail to create migration instance: ", err) - } - - if err = migration.Up(); err != nil { - log.Fatal("fail to run migrate up: ", err) - } - - log.Println("migration is successfully") -} - -func runGinServer(store db.Store, config utils.Config) { - server, err := api.NewServer(store, config) - if err != nil { - log.Fatal("Cannot create server") - } - - if err = server.Start(config.HttpServerAddress); err != nil { - log.Fatal("Cannot start server") - } -} - -func runGRPCServer(store db.Store, config utils.Config) { - server, err := gapi.NewServer(store, config) - if err != nil { - log.Fatalf("Cannot create gRPC server: %s", err) - } - - gRPCServer := grpc.NewServer() - pb.RegisterSimpleBankServer(gRPCServer, server) - // allow client to know what RPCs currently available in server - reflection.Register(gRPCServer) - - listener, err := net.Listen("tcp", config.GrpcServerAddress) - if err != nil { - log.Fatalf("Cannot create tcp-listener for gRPC server: %s", err) - } - - log.Printf("start gRPC server at: %s", listener.Addr().String()) - if err = gRPCServer.Serve(listener); err != nil { - log.Fatalf("Cannot serve gRPC server: %s", err) - } -} - -func runGatewayServer(store db.Store, config utils.Config) { - server, err := gapi.NewServer(store, config) - if err != nil { - log.Fatalf("Cannot create gRPC server: %s", err) - } - - jsonOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ - MarshalOptions: protojson.MarshalOptions{ - UseProtoNames: true, - }, - UnmarshalOptions: protojson.UnmarshalOptions{ - DiscardUnknown: true, - }, - }) - - grpcMux := runtime.NewServeMux(jsonOpts) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - if err = pb.RegisterSimpleBankHandlerServer(ctx, grpcMux, server); err != nil { - log.Fatalf("Cannot register handler server: %s", err) - } - - mux := http.NewServeMux() - mux.Handle("/", grpcMux) - - fs := http.FileServer(http.Dir("./doc/swagger")) - mux.Handle("/swagger/", http.StripPrefix("/swagger/", fs)) - - listener, err := net.Listen("tcp", config.HttpServerAddress) - if err != nil { - log.Fatalf("Cannot create tcp-listener for gateway server: %s", err) - } - - log.Printf("start HTTP gateway server at: %s", listener.Addr().String()) - if err = http.Serve(listener, mux); err != nil { - log.Fatalf("cannot HTTP gateway server: %s", err) - } -} diff --git a/db/migration/000001_init_schema.down.sql b/migration/000001_init_schema.down.sql similarity index 100% rename from db/migration/000001_init_schema.down.sql rename to migration/000001_init_schema.down.sql diff --git a/db/migration/000001_init_schema.up.sql b/migration/000001_init_schema.up.sql similarity index 100% rename from db/migration/000001_init_schema.up.sql rename to migration/000001_init_schema.up.sql diff --git a/db/migration/000002_add_users.down.sql b/migration/000002_add_users.down.sql similarity index 100% rename from db/migration/000002_add_users.down.sql rename to migration/000002_add_users.down.sql diff --git a/db/migration/000002_add_users.up.sql b/migration/000002_add_users.up.sql similarity index 100% rename from db/migration/000002_add_users.up.sql rename to migration/000002_add_users.up.sql diff --git a/db/migration/000003_add_sessions.down.sql b/migration/000003_add_sessions.down.sql similarity index 100% rename from db/migration/000003_add_sessions.down.sql rename to migration/000003_add_sessions.down.sql diff --git a/db/migration/000003_add_sessions.up.sql b/migration/000003_add_sessions.up.sql similarity index 100% rename from db/migration/000003_add_sessions.up.sql rename to migration/000003_add_sessions.up.sql diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go new file mode 100644 index 0000000..9a30d61 --- /dev/null +++ b/pkg/grpc/server.go @@ -0,0 +1,107 @@ +package grpc + +import ( + "context" + "github.com/cukhoaimon/SimpleBank/internal/delivery/grpc/gapi" + "github.com/cukhoaimon/SimpleBank/internal/delivery/grpc/pb" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + token2 "github.com/cukhoaimon/SimpleBank/pkg/token" + "github.com/cukhoaimon/SimpleBank/utils" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "google.golang.org/protobuf/encoding/protojson" + "log" + "net" + "net/http" +) + +// Server serves gRPC request +type Server struct { + pb.UnimplementedSimpleBankServer + Handler *gapi.Handler +} + +// NewServer will return new gRPC server +func NewServer(store db.Store, config utils.Config) (*Server, error) { + maker, err := token2.NewPasetoMaker(config.TokenSymmetricKey) + if err != nil { + return nil, err + } + + handler := &gapi.Handler{ + Store: store, + TokenMaker: maker, + Config: config, + } + + server := &Server{Handler: handler} + + return server, nil +} + +// Run will run gRPC server with provided store and config +func Run(store db.Store, config utils.Config) { + server, err := NewServer(store, config) + if err != nil { + log.Fatalf("Cannot create gRPC server: %s", err) + } + + gRPCServer := grpc.NewServer() + pb.RegisterSimpleBankServer(gRPCServer, server) + // allow client to know what RPCs currently available in server + reflection.Register(gRPCServer) + + listener, err := net.Listen("tcp", config.GrpcServerAddress) + if err != nil { + log.Fatalf("Cannot create tcp-listener for gRPC server: %s", err) + } + + log.Printf("start gRPC server at: %s", listener.Addr().String()) + if err = gRPCServer.Serve(listener); err != nil { + log.Fatalf("Cannot serve gRPC server: %s", err) + } +} + +// RunGatewayServer will run gRPC Gateway with provided store and config +// to serve HTTP Request +func RunGatewayServer(store db.Store, config utils.Config) { + server, err := NewServer(store, config) + if err != nil { + log.Fatalf("Cannot create gRPC server: %s", err) + } + + jsonOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + UseProtoNames: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: true, + }, + }) + + grpcMux := runtime.NewServeMux(jsonOpts) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if err = pb.RegisterSimpleBankHandlerServer(ctx, grpcMux, server); err != nil { + log.Fatalf("Cannot register handler server: %s", err) + } + + mux := http.NewServeMux() + mux.Handle("/", grpcMux) + + fs := http.FileServer(http.Dir("./docs/swagger")) + mux.Handle("/swagger/", http.StripPrefix("/swagger/", fs)) + + listener, err := net.Listen("tcp", config.HttpServerAddress) + if err != nil { + log.Fatalf("Cannot create tcp-listener for gateway server: %s", err) + } + + log.Printf("start HTTP gateway server at: %s", listener.Addr().String()) + if err = http.Serve(listener, mux); err != nil { + log.Fatalf("cannot HTTP gateway server: %s", err) + } +} diff --git a/pkg/http/server.go b/pkg/http/server.go new file mode 100644 index 0000000..c39e911 --- /dev/null +++ b/pkg/http/server.go @@ -0,0 +1,38 @@ +package http + +import ( + "github.com/cukhoaimon/SimpleBank/internal/delivery/http" + db "github.com/cukhoaimon/SimpleBank/internal/usecase/sqlc" + "github.com/cukhoaimon/SimpleBank/utils" + "log" +) + +type Server struct { + Handler *http.Handler +} + +// NewServer will return new HTTP server and setup Router +func NewServer(store db.Store, config utils.Config) (*Server, error) { + handler, err := http.NewHandler(store, config) + if err != nil { + return nil, err + } + + return &Server{Handler: handler}, nil +} + +func (server *Server) Start(address string) error { + return server.Handler.Router.Run(address) +} + +// Run will run Gin server to serve http request +func Run(store db.Store, config utils.Config) { + server, err := NewServer(store, config) + if err != nil { + log.Fatal("Cannot create server") + } + + if err = server.Start(config.HttpServerAddress); err != nil { + log.Fatal("Cannot start server") + } +} diff --git a/token/jwt_maker.go b/pkg/token/jwt_maker.go similarity index 100% rename from token/jwt_maker.go rename to pkg/token/jwt_maker.go diff --git a/token/jwt_maker_test.go b/pkg/token/jwt_maker_test.go similarity index 100% rename from token/jwt_maker_test.go rename to pkg/token/jwt_maker_test.go diff --git a/token/maker.go b/pkg/token/maker.go similarity index 100% rename from token/maker.go rename to pkg/token/maker.go diff --git a/token/paseto_maker.go b/pkg/token/paseto_maker.go similarity index 100% rename from token/paseto_maker.go rename to pkg/token/paseto_maker.go diff --git a/token/paseto_maker_test.go b/pkg/token/paseto_maker_test.go similarity index 100% rename from token/paseto_maker_test.go rename to pkg/token/paseto_maker_test.go diff --git a/token/payload.go b/pkg/token/payload.go similarity index 100% rename from token/payload.go rename to pkg/token/payload.go diff --git a/sqlc.yaml b/sqlc.yaml index c6dd24c..b8464a1 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -1,12 +1,20 @@ -version: "1" -packages: - - name: "db" - path: "./db/sqlc" - queries: "./db/query/" - schema: "./db/migration/" +version: 2 +plugins: + - name: golang + wasm: + url: "https://downloads.sqlc.dev/plugin/sqlc-gen-go_1.2.0.wasm" + sha256: "965d73d22711eee3a210565e66f918b8cb831c5f5b612e680642a4a785dd1ca1" +sql: + - schema: "./migration" + queries: "./internal/usecase/query/" engine: "postgresql" - emit_json_tags: true - emit_prepared_queries: false - emit_interface: true - emit_exact_table_names: false - emit_empty_slices: true + codegen: + - plugin: golang + out: "./internal/usecase/sqlc" + options: + package: "usecase" + emit_json_tags: true + emit_prepared_queries: false + emit_interface: true + emit_exact_table_names: false + emit_empty_slices: true