├── .air.toml ├── .gitignore ├── Golang_API.postman_collection.json ├── Makefile ├── client ├── createPost_client.go ├── deletePost_client.go ├── geMe_client.go ├── getPost_client.go ├── listPosts_client.go ├── signin_client.go ├── signup_client.go └── updatePost_client.go ├── cmd ├── client │ └── main.go └── server │ └── main.go ├── config └── default.go ├── controllers ├── auth.controller.go ├── post.controller.go └── user.controller.go ├── docker-compose.yml ├── example.env ├── gapi ├── auth-server.go ├── post-server.go ├── rpc_create_post.go ├── rpc_delete_post.go ├── rpc_get_me.go ├── rpc_get_post.go ├── rpc_list_posts.go ├── rpc_signin_user.go ├── rpc_signup_user.go ├── rpc_update_post.go ├── rpc_verify_user.go └── user-server.go ├── go.mod ├── go.sum ├── middleware └── deserialize-user.go ├── models ├── post.model.go └── user.model.go ├── pb ├── auth_service.pb.go ├── auth_service_grpc.pb.go ├── post.pb.go ├── post_service.pb.go ├── post_service_grpc.pb.go ├── rpc_create_post.pb.go ├── rpc_signin_user.pb.go ├── rpc_signup_user.pb.go ├── rpc_update_post.pb.go ├── user.pb.go ├── user_service.pb.go └── user_service_grpc.pb.go ├── proto-gen.sh ├── proto ├── auth_service.proto ├── post.proto ├── post_service.proto ├── rpc_create_post.proto ├── rpc_signin_user.proto ├── rpc_signup_user.proto ├── rpc_update_post.proto ├── user.proto └── user_service.proto ├── readMe.md ├── routes ├── auth.routes.go ├── post.routes.go └── user.routes.go ├── services ├── auth.service.go ├── auth.service.impl.go ├── post.service.go ├── post.service.impl.go ├── user.service.go └── user.service.impl.go ├── templates ├── base.html ├── resetPassword.html ├── styles.html └── verificationCode.html └── utils ├── email.go ├── encode.go ├── helper.go ├── password.go └── token.go /.air.toml: -------------------------------------------------------------------------------- 1 | root = "." 2 | testdata_dir = "testdata" 3 | tmp_dir = "tmp" 4 | 5 | [build] 6 | bin = "./tmp/main.exe" 7 | cmd = "go build -o ./tmp/main.exe ./cmd/server/main.go" 8 | delay = 1000 9 | exclude_dir = ["assets", "tmp", "vendor", "testdata"] 10 | exclude_file = [] 11 | exclude_regex = ["_test.go"] 12 | exclude_unchanged = false 13 | follow_symlink = false 14 | full_bin = "" 15 | include_dir = [] 16 | include_ext = ["go", "tpl", "tmpl", "html"] 17 | kill_delay = "0s" 18 | log = "build-errors.log" 19 | send_interrupt = false 20 | stop_on_error = true 21 | 22 | [color] 23 | app = "" 24 | build = "yellow" 25 | main = "magenta" 26 | runner = "green" 27 | watcher = "cyan" 28 | 29 | [log] 30 | time = false 31 | 32 | [misc] 33 | clean_on_exit = false 34 | 35 | [screen] 36 | clear_on_rebuild = false 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | .DS_Store 17 | TODO.md 18 | logs.txt 19 | .idea/ 20 | secret.md 21 | app.env 22 | /temp 23 | temp/ -------------------------------------------------------------------------------- /Golang_API.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "112e818d-eb80-4ac7-bd1f-181e32484495", 4 | "name": "Golang_API", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", 6 | "_exporter_id": "14791724" 7 | }, 8 | "item": [ 9 | { 10 | "name": "Auth", 11 | "item": [ 12 | { 13 | "name": "Register", 14 | "request": { 15 | "method": "POST", 16 | "header": [], 17 | "body": { 18 | "mode": "raw", 19 | "raw": "{\r\n \"email\": \"admin@admin.com\",\r\n \"name\": \"Admin\",\r\n \"photo\": \"default.png\",\r\n \"password\": \"password123\",\r\n \"passwordConfirm\": \"password123\"\r\n}", 20 | "options": { 21 | "raw": { 22 | "language": "json" 23 | } 24 | } 25 | }, 26 | "url": { 27 | "raw": "localhost:8000/api/auth/register", 28 | "host": [ 29 | "localhost" 30 | ], 31 | "port": "8000", 32 | "path": [ 33 | "api", 34 | "auth", 35 | "register" 36 | ] 37 | } 38 | }, 39 | "response": [] 40 | }, 41 | { 42 | "name": "Refresh Token", 43 | "request": { 44 | "method": "GET", 45 | "header": [], 46 | "url": { 47 | "raw": "localhost:8000/api/auth/refresh", 48 | "host": [ 49 | "localhost" 50 | ], 51 | "port": "8000", 52 | "path": [ 53 | "api", 54 | "auth", 55 | "refresh" 56 | ] 57 | } 58 | }, 59 | "response": [] 60 | }, 61 | { 62 | "name": "Logout", 63 | "request": { 64 | "method": "GET", 65 | "header": [], 66 | "url": { 67 | "raw": "localhost:8000/api/auth/logout", 68 | "host": [ 69 | "localhost" 70 | ], 71 | "port": "8000", 72 | "path": [ 73 | "api", 74 | "auth", 75 | "logout" 76 | ] 77 | } 78 | }, 79 | "response": [] 80 | }, 81 | { 82 | "name": "Login", 83 | "request": { 84 | "method": "POST", 85 | "header": [], 86 | "body": { 87 | "mode": "raw", 88 | "raw": "{\r\n \"email\": \"admin@admin.com\",\r\n \"password\": \"password123\"\r\n}", 89 | "options": { 90 | "raw": { 91 | "language": "json" 92 | } 93 | } 94 | }, 95 | "url": { 96 | "raw": "localhost:8000/api/auth/login", 97 | "host": [ 98 | "localhost" 99 | ], 100 | "port": "8000", 101 | "path": [ 102 | "api", 103 | "auth", 104 | "login" 105 | ] 106 | } 107 | }, 108 | "response": [] 109 | }, 110 | { 111 | "name": "Verify Email Address", 112 | "request": { 113 | "method": "GET", 114 | "header": [], 115 | "url": { 116 | "raw": "{{host}}/api/auth/verifyemail/M3ypLxqQMEMgRgWHwxee", 117 | "host": [ 118 | "{{host}}" 119 | ], 120 | "path": [ 121 | "api", 122 | "auth", 123 | "verifyemail", 124 | "M3ypLxqQMEMgRgWHwxee" 125 | ] 126 | } 127 | }, 128 | "response": [] 129 | } 130 | ] 131 | }, 132 | { 133 | "name": "User", 134 | "item": [ 135 | { 136 | "name": "Get Me", 137 | "request": { 138 | "method": "GET", 139 | "header": [], 140 | "url": { 141 | "raw": "localhost:8000/api/users/me", 142 | "host": [ 143 | "localhost" 144 | ], 145 | "port": "8000", 146 | "path": [ 147 | "api", 148 | "users", 149 | "me" 150 | ] 151 | } 152 | }, 153 | "response": [] 154 | } 155 | ] 156 | }, 157 | { 158 | "name": "Post", 159 | "item": [ 160 | { 161 | "name": "Create Post", 162 | "request": { 163 | "method": "POST", 164 | "header": [], 165 | "body": { 166 | "mode": "raw", 167 | "raw": "{\r\n \"title\": \"My first Python FASTAPI app project\",\r\n \"category\": \"Python\",\r\n \"content\": \"My content haha My content haha\",\r\n \"image\": \"default.png\"\r\n}", 168 | "options": { 169 | "raw": { 170 | "language": "json" 171 | } 172 | } 173 | }, 174 | "url": { 175 | "raw": "localhost:8000/api/posts", 176 | "host": [ 177 | "localhost" 178 | ], 179 | "port": "8000", 180 | "path": [ 181 | "api", 182 | "posts" 183 | ] 184 | } 185 | }, 186 | "response": [] 187 | }, 188 | { 189 | "name": "Get Post", 190 | "request": { 191 | "method": "GET", 192 | "header": [], 193 | "url": { 194 | "raw": "localhost:8000/api/posts/328cd0be-eeac-4be4-b764-7d3dc95695b2", 195 | "host": [ 196 | "localhost" 197 | ], 198 | "port": "8000", 199 | "path": [ 200 | "api", 201 | "posts", 202 | "328cd0be-eeac-4be4-b764-7d3dc95695b2" 203 | ] 204 | } 205 | }, 206 | "response": [] 207 | }, 208 | { 209 | "name": "Update Post", 210 | "request": { 211 | "method": "PATCH", 212 | "header": [], 213 | "body": { 214 | "mode": "raw", 215 | "raw": "{\r\n \"title\": \"Updated My first golang GORM app project\",\r\n \"category\": \"Golang\"\r\n}", 216 | "options": { 217 | "raw": { 218 | "language": "json" 219 | } 220 | } 221 | }, 222 | "url": { 223 | "raw": "localhost:8000/api/posts/e891ac2e-5371-45e3-a0d4-781e8c365905", 224 | "host": [ 225 | "localhost" 226 | ], 227 | "port": "8000", 228 | "path": [ 229 | "api", 230 | "posts", 231 | "e891ac2e-5371-45e3-a0d4-781e8c365905" 232 | ] 233 | } 234 | }, 235 | "response": [] 236 | }, 237 | { 238 | "name": "Delete Post", 239 | "request": { 240 | "method": "DELETE", 241 | "header": [], 242 | "url": { 243 | "raw": "localhost:8000/api/posts/66e1374e-d1f5-4e70-ad61-1a014ba8309b", 244 | "host": [ 245 | "localhost" 246 | ], 247 | "port": "8000", 248 | "path": [ 249 | "api", 250 | "posts", 251 | "66e1374e-d1f5-4e70-ad61-1a014ba8309b" 252 | ] 253 | } 254 | }, 255 | "response": [] 256 | }, 257 | { 258 | "name": "Get All Posts", 259 | "request": { 260 | "method": "GET", 261 | "header": [], 262 | "url": { 263 | "raw": "localhost:8000/api/posts?page=1&limit=10", 264 | "host": [ 265 | "localhost" 266 | ], 267 | "port": "8000", 268 | "path": [ 269 | "api", 270 | "posts" 271 | ], 272 | "query": [ 273 | { 274 | "key": "page", 275 | "value": "1" 276 | }, 277 | { 278 | "key": "limit", 279 | "value": "10" 280 | } 281 | ] 282 | } 283 | }, 284 | "response": [] 285 | }, 286 | { 287 | "name": "Health Checker", 288 | "request": { 289 | "method": "GET", 290 | "header": [], 291 | "url": { 292 | "raw": "http://localhost:8000/api/healthchecker", 293 | "protocol": "http", 294 | "host": [ 295 | "localhost" 296 | ], 297 | "port": "8000", 298 | "path": [ 299 | "api", 300 | "healthchecker" 301 | ] 302 | } 303 | }, 304 | "response": [] 305 | } 306 | ] 307 | } 308 | ] 309 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: dev dev-down go proto 2 | 3 | dev: 4 | docker-compose up -d 5 | 6 | dev-down: 7 | docker-compose down 8 | 9 | go: 10 | air 11 | 12 | proto: 13 | protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \ 14 | --go-grpc_out=pb --go-grpc_opt=paths=source_relative \ 15 | proto/*.proto -------------------------------------------------------------------------------- /client/createPost_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type CreatePostClient struct { 14 | service pb.PostServiceClient 15 | } 16 | 17 | func NewCreatePostClient(conn *grpc.ClientConn) *CreatePostClient { 18 | service := pb.NewPostServiceClient(conn) 19 | 20 | return &CreatePostClient{service} 21 | } 22 | 23 | func (createPostClient *CreatePostClient) CreatePost(args *pb.CreatePostRequest) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | res, err := createPostClient.service.CreatePost(ctx, args) 29 | 30 | if err != nil { 31 | log.Fatalf("CreatePost: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /client/deletePost_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type DeletePostClient struct { 14 | service pb.PostServiceClient 15 | } 16 | 17 | func NewDeletePostClient(conn *grpc.ClientConn) *DeletePostClient { 18 | service := pb.NewPostServiceClient(conn) 19 | 20 | return &DeletePostClient{service} 21 | } 22 | 23 | func (deletePostClient *DeletePostClient) DeletePost(args *pb.PostRequest) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | _, err := deletePostClient.service.DeletePost(ctx, args) 29 | 30 | if err != nil { 31 | log.Fatalf("DeletePost: %v", err) 32 | } 33 | 34 | fmt.Println("Post deleted successfully") 35 | } 36 | -------------------------------------------------------------------------------- /client/geMe_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type GetMeClient struct { 14 | service pb.UserServiceClient 15 | } 16 | 17 | func NewGetMeClient(conn *grpc.ClientConn) *GetMeClient { 18 | service := pb.NewUserServiceClient(conn) 19 | 20 | return &GetMeClient{service} 21 | } 22 | 23 | func (getMeClient *GetMeClient) GetMeUser(credentials *pb.GetMeRequest) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | res, err := getMeClient.service.GetMe(ctx, credentials) 29 | 30 | if err != nil { 31 | log.Fatalf("GeMe: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /client/getPost_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type GetPostClient struct { 14 | service pb.PostServiceClient 15 | } 16 | 17 | func NewGetPostClient(conn *grpc.ClientConn) *GetPostClient { 18 | service := pb.NewPostServiceClient(conn) 19 | 20 | return &GetPostClient{service} 21 | } 22 | 23 | func (getPostClient *GetPostClient) GetPost(args *pb.PostRequest) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | res, err := getPostClient.service.GetPost(ctx, args) 29 | 30 | if err != nil { 31 | log.Fatalf("GetPost: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /client/listPosts_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | "time" 9 | 10 | "github.com/wpcodevo/golang-mongodb/pb" 11 | "google.golang.org/grpc" 12 | ) 13 | 14 | type ListPostsClient struct { 15 | service pb.PostServiceClient 16 | } 17 | 18 | func NewListPostsClient(conn *grpc.ClientConn) *ListPostsClient { 19 | service := pb.NewPostServiceClient(conn) 20 | 21 | return &ListPostsClient{service} 22 | } 23 | 24 | func (listPostsClient *ListPostsClient) ListPosts(args *pb.GetPostsRequest) { 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | stream, err := listPostsClient.service.GetPosts(ctx, args) 29 | if err != nil { 30 | log.Fatalf("ListPosts: %v", err) 31 | } 32 | 33 | for { 34 | res, err := stream.Recv() 35 | 36 | if err == io.EOF { 37 | break 38 | } 39 | 40 | if err != nil { 41 | log.Fatalf("ListPosts: %v", err) 42 | } 43 | 44 | fmt.Println(res) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /client/signin_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type SignInUserClient struct { 14 | service pb.AuthServiceClient 15 | } 16 | 17 | func NewSignInUserClient(conn *grpc.ClientConn) *SignInUserClient { 18 | service := pb.NewAuthServiceClient(conn) 19 | 20 | return &SignInUserClient{service} 21 | } 22 | 23 | func (signInUserClient *SignInUserClient) SignInUser(credentials *pb.SignInUserInput) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Second) 26 | defer cancel() 27 | 28 | res, err := signInUserClient.service.SignInUser(ctx, credentials) 29 | 30 | if err != nil { 31 | log.Fatalf("SignInUser: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /client/signup_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type SignUpUserClient struct { 14 | service pb.AuthServiceClient 15 | } 16 | 17 | func NewSignUpUserClient(conn *grpc.ClientConn) *SignUpUserClient { 18 | service := pb.NewAuthServiceClient(conn) 19 | 20 | return &SignUpUserClient{service} 21 | } 22 | 23 | func (signUpUserClient *SignUpUserClient) SignUpUser(credentials *pb.SignUpUserInput) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | res, err := signUpUserClient.service.SignUpUser(ctx, credentials) 29 | 30 | if err != nil { 31 | log.Fatalf("SignUpUser: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /client/updatePost_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | type UpdatePostClient struct { 14 | service pb.PostServiceClient 15 | } 16 | 17 | func NewUpdatePostClient(conn *grpc.ClientConn) *UpdatePostClient { 18 | service := pb.NewPostServiceClient(conn) 19 | 20 | return &UpdatePostClient{service} 21 | } 22 | 23 | func (updatePostClient *UpdatePostClient) UpdatePost(args *pb.UpdatePostRequest) { 24 | 25 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*5000)) 26 | defer cancel() 27 | 28 | res, err := updatePostClient.service.UpdatePost(ctx, args) 29 | 30 | if err != nil { 31 | log.Fatalf("UpdatePost: %v", err) 32 | } 33 | 34 | fmt.Println(res) 35 | } 36 | -------------------------------------------------------------------------------- /cmd/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/wpcodevo/golang-mongodb/client" 7 | "github.com/wpcodevo/golang-mongodb/pb" 8 | "google.golang.org/grpc" 9 | "google.golang.org/grpc/credentials/insecure" 10 | ) 11 | 12 | const ( 13 | address = "0.0.0.0:8080" 14 | ) 15 | 16 | func main() { 17 | conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) 18 | 19 | if err != nil { 20 | log.Fatalf("failed to connect: %v", err) 21 | } 22 | 23 | defer conn.Close() 24 | 25 | // Sign Up 26 | if false { 27 | signUpUserClient := client.NewSignUpUserClient(conn) 28 | newUser := &pb.SignUpUserInput{ 29 | Name: "Jane Smith", 30 | Email: "janesmith@gmail.com", 31 | Password: "password123", 32 | PasswordConfirm: "password123", 33 | } 34 | signUpUserClient.SignUpUser(newUser) 35 | } 36 | 37 | // Sign In 38 | if false { 39 | signInUserClient := client.NewSignInUserClient(conn) 40 | 41 | credentials := &pb.SignInUserInput{ 42 | Email: "janesmith@gmail.com", 43 | Password: "password123", 44 | } 45 | signInUserClient.SignInUser(credentials) 46 | } 47 | 48 | // Get Me 49 | if false { 50 | 51 | getMeClient := client.NewGetMeClient(conn) 52 | id := &pb.GetMeRequest{ 53 | Id: "628cffb91e50302d360c1a2c", 54 | } 55 | getMeClient.GetMeUser(id) 56 | 57 | } 58 | 59 | // List Posts 60 | if false { 61 | listPostsClient := client.NewListPostsClient(conn) 62 | 63 | var page int64 = 1 64 | var limit int64 = 10 65 | args := &pb.GetPostsRequest{ 66 | Page: &page, 67 | Limit: &limit, 68 | } 69 | 70 | listPostsClient.ListPosts(args) 71 | } 72 | 73 | // Create Post 74 | if true { 75 | createPostClient := client.NewCreatePostClient(conn) 76 | 77 | args := &pb.CreatePostRequest{ 78 | Title: "My second gRPC post with joy", 79 | Content: "It's always good to learn new technologies", 80 | User: "62908e0a42a608d5aeae2f64", 81 | Image: "default.png", 82 | } 83 | 84 | createPostClient.CreatePost(args) 85 | } 86 | 87 | // Update Post 88 | if false { 89 | updatePostClient := client.NewUpdatePostClient(conn) 90 | 91 | title := "My new updated title for my blog" 92 | args := &pb.UpdatePostRequest{ 93 | Id: "629169e00a6c7cfd24e2129d", 94 | Title: &title, 95 | } 96 | 97 | updatePostClient.UpdatePost(args) 98 | } 99 | 100 | // Get Post 101 | if false { 102 | getPostClient := client.NewGetPostClient(conn) 103 | 104 | args := &pb.PostRequest{ 105 | Id: "629169e00a6c7cfd24e2129d", 106 | } 107 | 108 | getPostClient.GetPost(args) 109 | } 110 | 111 | // Delete Post 112 | if false { 113 | deletePostClient := client.NewDeletePostClient(conn) 114 | 115 | args := &pb.PostRequest{ 116 | Id: "629147ff3c92aed11d49394b", 117 | } 118 | 119 | deletePostClient.DeletePost(args) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /cmd/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "net" 8 | "net/http" 9 | 10 | "github.com/gin-contrib/cors" 11 | "github.com/gin-gonic/gin" 12 | "github.com/go-redis/redis/v8" 13 | "github.com/wpcodevo/golang-mongodb/config" 14 | "github.com/wpcodevo/golang-mongodb/controllers" 15 | "github.com/wpcodevo/golang-mongodb/gapi" 16 | "github.com/wpcodevo/golang-mongodb/pb" 17 | "github.com/wpcodevo/golang-mongodb/routes" 18 | "github.com/wpcodevo/golang-mongodb/services" 19 | "go.mongodb.org/mongo-driver/mongo" 20 | "go.mongodb.org/mongo-driver/mongo/options" 21 | "go.mongodb.org/mongo-driver/mongo/readpref" 22 | "google.golang.org/grpc" 23 | "google.golang.org/grpc/reflection" 24 | ) 25 | 26 | var ( 27 | server *gin.Engine 28 | ctx context.Context 29 | mongoclient *mongo.Client 30 | redisclient *redis.Client 31 | 32 | userService services.UserService 33 | UserController controllers.UserController 34 | UserRouteController routes.UserRouteController 35 | 36 | authCollection *mongo.Collection 37 | authService services.AuthService 38 | AuthController controllers.AuthController 39 | AuthRouteController routes.AuthRouteController 40 | 41 | // 👇 Create the Post Variables 42 | postService services.PostService 43 | PostController controllers.PostController 44 | postCollection *mongo.Collection 45 | PostRouteController routes.PostRouteController 46 | ) 47 | 48 | func init() { 49 | config, err := config.LoadConfig(".") 50 | if err != nil { 51 | log.Fatal("Could not load environment variables", err) 52 | } 53 | 54 | ctx = context.TODO() 55 | 56 | // Connect to MongoDB 57 | mongoconn := options.Client().ApplyURI(config.DBUri) 58 | mongoclient, err := mongo.Connect(ctx, mongoconn) 59 | 60 | if err != nil { 61 | panic(err) 62 | } 63 | 64 | if err := mongoclient.Ping(ctx, readpref.Primary()); err != nil { 65 | panic(err) 66 | } 67 | 68 | fmt.Println("MongoDB successfully connected...") 69 | 70 | // Connect to Redis 71 | redisclient = redis.NewClient(&redis.Options{ 72 | Addr: config.RedisUri, 73 | }) 74 | 75 | if _, err := redisclient.Ping(ctx).Result(); err != nil { 76 | panic(err) 77 | } 78 | 79 | err = redisclient.Set(ctx, "test", "Welcome to Golang with Redis and MongoDB", 0).Err() 80 | if err != nil { 81 | panic(err) 82 | } 83 | 84 | fmt.Println("Redis client connected successfully...") 85 | 86 | // Collections 87 | authCollection = mongoclient.Database("golang_mongodb").Collection("users") 88 | userService = services.NewUserServiceImpl(authCollection, ctx) 89 | authService = services.NewAuthService(authCollection, ctx) 90 | AuthController = controllers.NewAuthController(authService, userService, ctx, authCollection) 91 | AuthRouteController = routes.NewAuthRouteController(AuthController) 92 | 93 | UserController = controllers.NewUserController(userService) 94 | UserRouteController = routes.NewRouteUserController(UserController) 95 | 96 | // 👇 Instantiate the Constructors 97 | postCollection = mongoclient.Database("golang_mongodb").Collection("posts") 98 | postService = services.NewPostService(postCollection, ctx) 99 | PostController = controllers.NewPostController(postService) 100 | PostRouteController = routes.NewPostControllerRoute(PostController) 101 | 102 | server = gin.Default() 103 | } 104 | 105 | func main() { 106 | config, err := config.LoadConfig(".") 107 | 108 | if err != nil { 109 | log.Fatal("Could not load config", err) 110 | } 111 | 112 | defer mongoclient.Disconnect(ctx) 113 | 114 | // Start gRPC server in a separate goroutine 115 | go startGrpcServer(config) 116 | 117 | // Start Gin server in the main goroutine 118 | startGinServer(config) 119 | 120 | } 121 | 122 | func startGrpcServer(config config.Config) { 123 | authServer, err := gapi.NewGrpcAuthServer(config, authService, userService, authCollection) 124 | if err != nil { 125 | log.Fatal("cannot create grpc authServer: ", err) 126 | } 127 | 128 | userServer, err := gapi.NewGrpcUserServer(config, userService, authCollection) 129 | if err != nil { 130 | log.Fatal("cannot create grpc userServer: ", err) 131 | } 132 | 133 | postServer, err := gapi.NewGrpcPostServer(postCollection, postService) 134 | if err != nil { 135 | log.Fatal("cannot create grpc postServer: ", err) 136 | } 137 | 138 | grpcServer := grpc.NewServer() 139 | 140 | pb.RegisterAuthServiceServer(grpcServer, authServer) 141 | pb.RegisterUserServiceServer(grpcServer, userServer) 142 | // 👇 Register the Post gRPC service 143 | pb.RegisterPostServiceServer(grpcServer, postServer) 144 | reflection.Register(grpcServer) 145 | 146 | listener, err := net.Listen("tcp", config.GrpcServerAddress) 147 | if err != nil { 148 | log.Fatal("cannot create grpc server: ", err) 149 | } 150 | 151 | log.Printf("start gRPC server on %s", listener.Addr().String()) 152 | err = grpcServer.Serve(listener) 153 | if err != nil { 154 | log.Fatal("cannot create grpc server: ", err) 155 | } 156 | } 157 | 158 | func startGinServer(config config.Config) { 159 | value, err := redisclient.Get(ctx, "test").Result() 160 | 161 | if err == redis.Nil { 162 | fmt.Println("key: test does not exist") 163 | } else if err != nil { 164 | panic(err) 165 | } 166 | 167 | corsConfig := cors.DefaultConfig() 168 | corsConfig.AllowOrigins = []string{config.Origin} 169 | corsConfig.AllowCredentials = true 170 | 171 | server.Use(cors.New(corsConfig)) 172 | 173 | router := server.Group("/api") 174 | router.GET("/healthchecker", func(ctx *gin.Context) { 175 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": value}) 176 | }) 177 | 178 | AuthRouteController.AuthRoute(router, userService) 179 | UserRouteController.UserRoute(router, userService) 180 | // 👇 Post Route 181 | PostRouteController.PostRoute(router) 182 | log.Fatal(server.Run(":" + config.Port)) 183 | } 184 | -------------------------------------------------------------------------------- /config/default.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/spf13/viper" 7 | ) 8 | 9 | type Config struct { 10 | DBUri string `mapstructure:"MONGODB_LOCAL_URI"` 11 | RedisUri string `mapstructure:"REDIS_URL"` 12 | Port string `mapstructure:"PORT"` 13 | 14 | GrpcServerAddress string `mapstructure:"GRPC_SERVER_ADDRESS"` 15 | 16 | AccessTokenPrivateKey string `mapstructure:"ACCESS_TOKEN_PRIVATE_KEY"` 17 | AccessTokenPublicKey string `mapstructure:"ACCESS_TOKEN_PUBLIC_KEY"` 18 | RefreshTokenPrivateKey string `mapstructure:"REFRESH_TOKEN_PRIVATE_KEY"` 19 | RefreshTokenPublicKey string `mapstructure:"REFRESH_TOKEN_PUBLIC_KEY"` 20 | AccessTokenExpiresIn time.Duration `mapstructure:"ACCESS_TOKEN_EXPIRED_IN"` 21 | RefreshTokenExpiresIn time.Duration `mapstructure:"REFRESH_TOKEN_EXPIRED_IN"` 22 | AccessTokenMaxAge int `mapstructure:"ACCESS_TOKEN_MAXAGE"` 23 | RefreshTokenMaxAge int `mapstructure:"REFRESH_TOKEN_MAXAGE"` 24 | 25 | Origin string `mapstructure:"CLIENT_ORIGIN"` 26 | 27 | EmailFrom string `mapstructure:"EMAIL_FROM"` 28 | SMTPHost string `mapstructure:"SMTP_HOST"` 29 | SMTPPass string `mapstructure:"SMTP_PASS"` 30 | SMTPPort int `mapstructure:"SMTP_PORT"` 31 | SMTPUser string `mapstructure:"SMTP_USER"` 32 | } 33 | 34 | func LoadConfig(path string) (config Config, err error) { 35 | viper.AddConfigPath(path) 36 | viper.SetConfigType("env") 37 | viper.SetConfigName("app") 38 | 39 | viper.AutomaticEnv() 40 | 41 | err = viper.ReadInConfig() 42 | if err != nil { 43 | return 44 | } 45 | 46 | err = viper.Unmarshal(&config) 47 | return 48 | } 49 | -------------------------------------------------------------------------------- /controllers/auth.controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | "strings" 9 | "time" 10 | 11 | "github.com/gin-gonic/gin" 12 | "github.com/thanhpk/randstr" 13 | "github.com/wpcodevo/golang-mongodb/config" 14 | "github.com/wpcodevo/golang-mongodb/models" 15 | "github.com/wpcodevo/golang-mongodb/services" 16 | "github.com/wpcodevo/golang-mongodb/utils" 17 | "go.mongodb.org/mongo-driver/bson" 18 | "go.mongodb.org/mongo-driver/mongo" 19 | ) 20 | 21 | type AuthController struct { 22 | authService services.AuthService 23 | userService services.UserService 24 | ctx context.Context 25 | collection *mongo.Collection 26 | } 27 | 28 | func NewAuthController(authService services.AuthService, userService services.UserService, ctx context.Context, collection *mongo.Collection) AuthController { 29 | return AuthController{authService, userService, ctx, collection} 30 | } 31 | 32 | func (ac *AuthController) SignUpUser(ctx *gin.Context) { 33 | var user *models.SignUpInput 34 | 35 | if err := ctx.ShouldBindJSON(&user); err != nil { 36 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 37 | return 38 | } 39 | 40 | if user.Password != user.PasswordConfirm { 41 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": "Passwords do not match"}) 42 | return 43 | } 44 | 45 | newUser, err := ac.authService.SignUpUser(user) 46 | 47 | if err != nil { 48 | if strings.Contains(err.Error(), "email already exist") { 49 | ctx.JSON(http.StatusConflict, gin.H{"status": "error", "message": err.Error()}) 50 | return 51 | } 52 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "error", "message": err.Error()}) 53 | return 54 | } 55 | 56 | config, err := config.LoadConfig(".") 57 | if err != nil { 58 | log.Fatal("Could not load config", err) 59 | } 60 | 61 | // Generate Verification Code 62 | code := randstr.String(20) 63 | 64 | verificationCode := utils.Encode(code) 65 | 66 | updateData := &models.UpdateInput{ 67 | VerificationCode: verificationCode, 68 | } 69 | 70 | // Update User in Database 71 | ac.userService.UpdateUserById(newUser.ID.Hex(), updateData) 72 | 73 | var firstName = newUser.Name 74 | 75 | if strings.Contains(firstName, " ") { 76 | firstName = strings.Split(firstName, " ")[1] 77 | } 78 | 79 | // 👇 Send Email 80 | emailData := utils.EmailData{ 81 | URL: config.Origin + "/verifyemail/" + code, 82 | FirstName: firstName, 83 | Subject: "Your account verification code", 84 | } 85 | 86 | err = utils.SendEmail(newUser, &emailData, "verificationCode.html") 87 | if err != nil { 88 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "success", "message": "There was an error sending email"}) 89 | return 90 | } 91 | 92 | message := "We sent an email with a verification code to " + user.Email 93 | ctx.JSON(http.StatusCreated, gin.H{"status": "success", "message": message}) 94 | } 95 | 96 | func (ac *AuthController) SignInUser(ctx *gin.Context) { 97 | var credentials *models.SignInInput 98 | 99 | if err := ctx.ShouldBindJSON(&credentials); err != nil { 100 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 101 | return 102 | } 103 | 104 | user, err := ac.userService.FindUserByEmail(credentials.Email) 105 | if err != nil { 106 | if err == mongo.ErrNoDocuments { 107 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": "Invalid email or password"}) 108 | return 109 | } 110 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 111 | return 112 | } 113 | 114 | if !user.Verified { 115 | ctx.JSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": "You are not verified, please verify your email to login"}) 116 | return 117 | } 118 | 119 | if err := utils.VerifyPassword(user.Password, credentials.Password); err != nil { 120 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": "Invalid email or Password"}) 121 | return 122 | } 123 | 124 | config, _ := config.LoadConfig(".") 125 | 126 | // Generate Tokens 127 | access_token, err := utils.CreateToken(config.AccessTokenExpiresIn, user.ID, config.AccessTokenPrivateKey) 128 | if err != nil { 129 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 130 | return 131 | } 132 | 133 | refresh_token, err := utils.CreateToken(config.RefreshTokenExpiresIn, user.ID, config.RefreshTokenPrivateKey) 134 | if err != nil { 135 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 136 | return 137 | } 138 | 139 | ctx.SetCookie("access_token", access_token, config.AccessTokenMaxAge*60, "/", "localhost", false, true) 140 | ctx.SetCookie("refresh_token", refresh_token, config.RefreshTokenMaxAge*60, "/", "localhost", false, true) 141 | ctx.SetCookie("logged_in", "true", config.AccessTokenMaxAge*60, "/", "localhost", false, false) 142 | 143 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "access_token": access_token}) 144 | } 145 | 146 | func (ac *AuthController) RefreshAccessToken(ctx *gin.Context) { 147 | message := "could not refresh access token" 148 | 149 | cookie, err := ctx.Cookie("refresh_token") 150 | 151 | if err != nil { 152 | ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": message}) 153 | return 154 | } 155 | 156 | config, _ := config.LoadConfig(".") 157 | 158 | sub, err := utils.ValidateToken(cookie, config.RefreshTokenPublicKey) 159 | if err != nil { 160 | ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": err.Error()}) 161 | return 162 | } 163 | 164 | user, err := ac.userService.FindUserById(fmt.Sprint(sub)) 165 | if err != nil { 166 | ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": "the user belonging to this token no logger exists"}) 167 | return 168 | } 169 | 170 | access_token, err := utils.CreateToken(config.AccessTokenExpiresIn, user.ID, config.AccessTokenPrivateKey) 171 | if err != nil { 172 | ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": err.Error()}) 173 | return 174 | } 175 | 176 | ctx.SetCookie("access_token", access_token, config.AccessTokenMaxAge*60, "/", "localhost", false, true) 177 | ctx.SetCookie("logged_in", "true", config.AccessTokenMaxAge*60, "/", "localhost", false, false) 178 | 179 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "access_token": access_token}) 180 | } 181 | 182 | func (ac *AuthController) LogoutUser(ctx *gin.Context) { 183 | ctx.SetCookie("access_token", "", -1, "/", "localhost", false, true) 184 | ctx.SetCookie("refresh_token", "", -1, "/", "localhost", false, true) 185 | ctx.SetCookie("logged_in", "", -1, "/", "localhost", false, true) 186 | 187 | ctx.JSON(http.StatusOK, gin.H{"status": "success"}) 188 | } 189 | 190 | func (ac *AuthController) VerifyEmail(ctx *gin.Context) { 191 | 192 | code := ctx.Params.ByName("verificationCode") 193 | verificationCode := utils.Encode(code) 194 | 195 | query := bson.D{{Key: "verificationCode", Value: verificationCode}} 196 | update := bson.D{{Key: "$set", Value: bson.D{{Key: "verified", Value: true}}}, {Key: "$unset", Value: bson.D{{Key: "verificationCode", Value: ""}}}} 197 | result, err := ac.collection.UpdateOne(ac.ctx, query, update) 198 | if err != nil { 199 | ctx.JSON(http.StatusForbidden, gin.H{"status": "success", "message": err.Error()}) 200 | return 201 | } 202 | 203 | if result.MatchedCount == 0 { 204 | ctx.JSON(http.StatusForbidden, gin.H{"status": "success", "message": "Could not verify email address"}) 205 | return 206 | } 207 | 208 | fmt.Println(result) 209 | 210 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": "Email verified successfully"}) 211 | 212 | } 213 | 214 | func (ac *AuthController) ForgotPassword(ctx *gin.Context) { 215 | var userCredential *models.ForgotPasswordInput 216 | 217 | if err := ctx.ShouldBindJSON(&userCredential); err != nil { 218 | ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()}) 219 | return 220 | } 221 | 222 | message := "You will receive a reset email if user with that email exist" 223 | 224 | user, err := ac.userService.FindUserByEmail(userCredential.Email) 225 | if err != nil { 226 | if err == mongo.ErrNoDocuments { 227 | ctx.JSON(http.StatusOK, gin.H{"status": "fail", "message": message}) 228 | return 229 | } 230 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "error", "message": err.Error()}) 231 | return 232 | } 233 | 234 | if !user.Verified { 235 | ctx.JSON(http.StatusUnauthorized, gin.H{"status": "error", "message": "Account not verified"}) 236 | return 237 | } 238 | 239 | config, err := config.LoadConfig(".") 240 | if err != nil { 241 | log.Fatal("Could not load config", err) 242 | } 243 | 244 | // Generate Verification Code 245 | resetToken := randstr.String(20) 246 | 247 | passwordResetToken := utils.Encode(resetToken) 248 | 249 | // Update User in Database 250 | query := bson.D{{Key: "email", Value: strings.ToLower(userCredential.Email)}} 251 | update := bson.D{{Key: "$set", Value: bson.D{{Key: "passwordResetToken", Value: passwordResetToken}, {Key: "passwordResetAt", Value: time.Now().Add(time.Minute * 15)}}}} 252 | result, err := ac.collection.UpdateOne(ac.ctx, query, update) 253 | 254 | if result.MatchedCount == 0 { 255 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "success", "message": "There was an error sending email"}) 256 | return 257 | } 258 | 259 | if err != nil { 260 | ctx.JSON(http.StatusForbidden, gin.H{"status": "success", "message": err.Error()}) 261 | return 262 | } 263 | var firstName = user.Name 264 | 265 | if strings.Contains(firstName, " ") { 266 | firstName = strings.Split(firstName, " ")[1] 267 | } 268 | 269 | // 👇 Send Email 270 | emailData := utils.EmailData{ 271 | URL: config.Origin + "/forgotPassword/" + resetToken, 272 | FirstName: firstName, 273 | Subject: "Your password reset token (valid for 10min)", 274 | } 275 | 276 | err = utils.SendEmail(user, &emailData, "resetPassword.html") 277 | if err != nil { 278 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "success", "message": "There was an error sending email"}) 279 | return 280 | } 281 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": message}) 282 | } 283 | -------------------------------------------------------------------------------- /controllers/post.controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "net/http" 5 | "strconv" 6 | "strings" 7 | 8 | "github.com/gin-gonic/gin" 9 | "github.com/wpcodevo/golang-mongodb/models" 10 | "github.com/wpcodevo/golang-mongodb/services" 11 | ) 12 | 13 | type PostController struct { 14 | postService services.PostService 15 | } 16 | 17 | func NewPostController(postService services.PostService) PostController { 18 | return PostController{postService} 19 | } 20 | 21 | func (pc *PostController) CreatePost(ctx *gin.Context) { 22 | var post *models.CreatePostRequest 23 | 24 | if err := ctx.ShouldBindJSON(&post); err != nil { 25 | ctx.JSON(http.StatusBadRequest, err.Error()) 26 | return 27 | } 28 | 29 | newPost, err := pc.postService.CreatePost(post) 30 | 31 | if err != nil { 32 | if strings.Contains(err.Error(), "title already exists") { 33 | ctx.JSON(http.StatusConflict, gin.H{"status": "fail", "message": err.Error()}) 34 | return 35 | } 36 | 37 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 38 | return 39 | } 40 | 41 | ctx.JSON(http.StatusCreated, gin.H{"status": "success", "data": newPost}) 42 | } 43 | 44 | func (pc *PostController) UpdatePost(ctx *gin.Context) { 45 | postId := ctx.Param("postId") 46 | 47 | var post *models.UpdatePost 48 | if err := ctx.ShouldBindJSON(&post); err != nil { 49 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 50 | return 51 | } 52 | 53 | updatedPost, err := pc.postService.UpdatePost(postId, post) 54 | if err != nil { 55 | if strings.Contains(err.Error(), "Id exists") { 56 | ctx.JSON(http.StatusNotFound, gin.H{"status": "fail", "message": err.Error()}) 57 | return 58 | } 59 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 60 | return 61 | } 62 | 63 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "data": updatedPost}) 64 | } 65 | 66 | func (pc *PostController) FindPostById(ctx *gin.Context) { 67 | postId := ctx.Param("postId") 68 | 69 | post, err := pc.postService.FindPostById(postId) 70 | 71 | if err != nil { 72 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 73 | return 74 | } 75 | 76 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "data": post}) 77 | } 78 | 79 | func (pc *PostController) FindPosts(ctx *gin.Context) { 80 | var page = ctx.DefaultQuery("page", "1") 81 | var limit = ctx.DefaultQuery("limit", "10") 82 | 83 | intPage, err := strconv.Atoi(page) 84 | if err != nil { 85 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 86 | return 87 | } 88 | 89 | intLimit, err := strconv.Atoi(limit) 90 | if err != nil { 91 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 92 | return 93 | } 94 | 95 | posts, err := pc.postService.FindPosts(intPage, intLimit) 96 | if err != nil { 97 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 98 | return 99 | } 100 | 101 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "results": len(posts), "data": posts}) 102 | } 103 | 104 | func (pc *PostController) DeletePost(ctx *gin.Context) { 105 | postId := ctx.Param("postId") 106 | 107 | err := pc.postService.DeletePost(postId) 108 | 109 | if err != nil { 110 | if strings.Contains(err.Error(), "Id exists") { 111 | ctx.JSON(http.StatusNotFound, gin.H{"status": "fail", "message": err.Error()}) 112 | return 113 | } 114 | ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()}) 115 | return 116 | } 117 | 118 | ctx.JSON(http.StatusNoContent, nil) 119 | } 120 | -------------------------------------------------------------------------------- /controllers/user.controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | "github.com/wpcodevo/golang-mongodb/models" 8 | "github.com/wpcodevo/golang-mongodb/services" 9 | ) 10 | 11 | type UserController struct { 12 | userService services.UserService 13 | } 14 | 15 | func NewUserController(userService services.UserService) UserController { 16 | return UserController{userService} 17 | } 18 | 19 | func (uc *UserController) GetMe(ctx *gin.Context) { 20 | currentUser := ctx.MustGet("currentUser").(*models.DBResponse) 21 | 22 | ctx.JSON(http.StatusOK, gin.H{"status": "success", "data": gin.H{"user": models.FilteredResponse(currentUser)}}) 23 | } 24 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mongodb: 4 | image: mongo 5 | container_name: mongodb 6 | restart: always 7 | env_file: 8 | - ./app.env 9 | 10 | ports: 11 | - '6000:27017' 12 | volumes: 13 | - mongodb:/data/db 14 | 15 | redis: 16 | image: redis:alpine 17 | container_name: redis 18 | ports: 19 | - '6379:6379' 20 | volumes: 21 | - redisDB:/data 22 | volumes: 23 | mongodb: 24 | redisDB: 25 | -------------------------------------------------------------------------------- /example.env: -------------------------------------------------------------------------------- 1 | PORT=8000 2 | 3 | GRPC_SERVER_ADDRESS=0.0.0.0:8080 4 | 5 | MONGO_INITDB_ROOT_USERNAME=root 6 | MONGO_INITDB_ROOT_PASSWORD=password123 7 | 8 | MONGODB_LOCAL_URI=mongodb://root:password123@localhost:6000 9 | 10 | REDIS_URL=localhost:6379 11 | 12 | CLIENT_ORIGIN=http://localhost:3000 13 | 14 | EMAIL_FROM=admin@admin.com 15 | SMTP_HOST=smtp.mailtrap.io 16 | SMTP_USER= 17 | SMTP_PASS= 18 | SMTP_PORT=587 19 | 20 | 21 | ACCESS_TOKEN_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCUEFJQkFBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VXNjbGFFKzlaUUg5Q2VpOGIxcUVmCnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUUpCQUw4ZjRBMUlDSWEvQ2ZmdWR3TGMKNzRCdCtwOXg0TEZaZXMwdHdtV3Vha3hub3NaV0w4eVpSTUJpRmI4a25VL0hwb3piTnNxMmN1ZU9wKzVWdGRXNApiTlVDSVFENm9JdWxqcHdrZTFGY1VPaldnaXRQSjNnbFBma3NHVFBhdFYwYnJJVVI5d0loQVBOanJ1enB4ckhsCkUxRmJxeGtUNFZ5bWhCOU1HazU0Wk1jWnVjSmZOcjBUQWlFQWhML3UxOVZPdlVBWVd6Wjc3Y3JxMTdWSFBTcXoKUlhsZjd2TnJpdEg1ZGdjQ0lRRHR5QmFPdUxuNDlIOFIvZ2ZEZ1V1cjg3YWl5UHZ1YStxeEpXMzQrb0tFNXdJZwpQbG1KYXZsbW9jUG4rTkVRdGhLcTZuZFVYRGpXTTlTbktQQTVlUDZSUEs0PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ== 22 | 23 | ACCESS_TOKEN_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VQpzY2xhRSs5WlFIOUNlaThiMXFFZnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ== 24 | ACCESS_TOKEN_EXPIRED_IN=15m 25 | ACCESS_TOKEN_MAXAGE=15 26 | 27 | 28 | REFRESH_TOKEN_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT1FJQkFBSkJBSWFJcXZXeldCSndnYjR1SEhFQ01RdHFZMTI5b2F5RzVZMGlGcG51a0J1VHpRZVlQWkE4Cmx4OC9lTUh3Rys1MlJGR3VxMmE2N084d2s3TDR5dnY5dVY4Q0F3RUFBUUpBRUZ6aEJqOUk3LzAxR285N01CZUgKSlk5TUJLUEMzVHdQQVdwcSswL3p3UmE2ZkZtbXQ5NXNrN21qT3czRzNEZ3M5T2RTeWdsbTlVdndNWXh6SXFERAplUUloQVA5UStrMTBQbGxNd2ZJbDZtdjdTMFRYOGJDUlRaZVI1ZFZZb3FTeW40YmpBaUVBaHVUa2JtZ1NobFlZCnRyclNWZjN0QWZJcWNVUjZ3aDdMOXR5MVlvalZVRlVDSUhzOENlVHkwOWxrbkVTV0dvV09ZUEZVemhyc3Q2Z08KU3dKa2F2VFdKdndEQWlBdWhnVU8yeEFBaXZNdEdwUHVtb3hDam8zNjBMNXg4d012bWdGcEFYNW9uUUlnQzEvSwpNWG1heWtsaFRDeWtXRnpHMHBMWVdkNGRGdTI5M1M2ZUxJUlNIS009Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t 29 | 30 | REFRESH_TOKEN_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBSWFJcXZXeldCSndnYjR1SEhFQ01RdHFZMTI5b2F5Rwo1WTBpRnBudWtCdVR6UWVZUFpBOGx4OC9lTUh3Rys1MlJGR3VxMmE2N084d2s3TDR5dnY5dVY4Q0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ== 31 | 32 | REFRESH_TOKEN_EXPIRED_IN=60m 33 | REFRESH_TOKEN_MAXAGE=60 34 | -------------------------------------------------------------------------------- /gapi/auth-server.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "github.com/wpcodevo/golang-mongodb/config" 5 | "github.com/wpcodevo/golang-mongodb/pb" 6 | "github.com/wpcodevo/golang-mongodb/services" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | ) 9 | 10 | type AuthServer struct { 11 | pb.UnimplementedAuthServiceServer 12 | config config.Config 13 | authService services.AuthService 14 | userService services.UserService 15 | userCollection *mongo.Collection 16 | } 17 | 18 | func NewGrpcAuthServer(config config.Config, authService services.AuthService, 19 | userService services.UserService, userCollection *mongo.Collection) (*AuthServer, error) { 20 | 21 | authServer := &AuthServer{ 22 | config: config, 23 | authService: authService, 24 | userService: userService, 25 | userCollection: userCollection, 26 | } 27 | 28 | return authServer, nil 29 | } 30 | -------------------------------------------------------------------------------- /gapi/post-server.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "github.com/wpcodevo/golang-mongodb/pb" 5 | "github.com/wpcodevo/golang-mongodb/services" 6 | "go.mongodb.org/mongo-driver/mongo" 7 | ) 8 | 9 | type PostServer struct { 10 | pb.UnimplementedPostServiceServer 11 | postCollection *mongo.Collection 12 | postService services.PostService 13 | } 14 | 15 | func NewGrpcPostServer(postCollection *mongo.Collection, postService services.PostService) (*PostServer, error) { 16 | postServer := &PostServer{ 17 | postCollection: postCollection, 18 | postService: postService, 19 | } 20 | 21 | return postServer, nil 22 | } 23 | -------------------------------------------------------------------------------- /gapi/rpc_create_post.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/wpcodevo/golang-mongodb/models" 8 | "github.com/wpcodevo/golang-mongodb/pb" 9 | "google.golang.org/grpc/codes" 10 | "google.golang.org/grpc/status" 11 | "google.golang.org/protobuf/types/known/timestamppb" 12 | ) 13 | 14 | func (postServer *PostServer) CreatePost(ctx context.Context, req *pb.CreatePostRequest) (*pb.PostResponse, error) { 15 | 16 | post := &models.CreatePostRequest{ 17 | Title: req.GetTitle(), 18 | Content: req.GetContent(), 19 | Image: req.GetImage(), 20 | User: req.GetUser(), 21 | } 22 | 23 | newPost, err := postServer.postService.CreatePost(post) 24 | 25 | if err != nil { 26 | if strings.Contains(err.Error(), "title already exists") { 27 | return nil, status.Errorf(codes.AlreadyExists, err.Error()) 28 | } 29 | 30 | return nil, status.Errorf(codes.Internal, err.Error()) 31 | } 32 | 33 | res := &pb.PostResponse{ 34 | Post: &pb.Post{ 35 | Id: newPost.Id.Hex(), 36 | Title: newPost.Title, 37 | Content: newPost.Content, 38 | User: newPost.User, 39 | CreatedAt: timestamppb.New(newPost.CreateAt), 40 | UpdatedAt: timestamppb.New(newPost.UpdatedAt), 41 | }, 42 | } 43 | return res, nil 44 | } 45 | -------------------------------------------------------------------------------- /gapi/rpc_delete_post.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/wpcodevo/golang-mongodb/pb" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/status" 10 | ) 11 | 12 | func (postServer *PostServer) DeletePost(ctx context.Context, req *pb.PostRequest) (*pb.DeletePostResponse, error) { 13 | postId := req.GetId() 14 | 15 | if err := postServer.postService.DeletePost(postId); err != nil { 16 | if strings.Contains(err.Error(), "Id exists") { 17 | return nil, status.Errorf(codes.NotFound, err.Error()) 18 | } 19 | return nil, status.Errorf(codes.Internal, err.Error()) 20 | } 21 | 22 | res := &pb.DeletePostResponse{ 23 | Success: true, 24 | } 25 | 26 | return res, nil 27 | } 28 | -------------------------------------------------------------------------------- /gapi/rpc_get_me.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/wpcodevo/golang-mongodb/pb" 7 | "google.golang.org/grpc/codes" 8 | "google.golang.org/grpc/status" 9 | "google.golang.org/protobuf/types/known/timestamppb" 10 | ) 11 | 12 | func (userServer *UserServer) GetMe(ctx context.Context, req *pb.GetMeRequest) (*pb.UserResponse, error) { 13 | id := req.GetId() 14 | user, err := userServer.userService.FindUserById(id) 15 | 16 | if err != nil { 17 | return nil, status.Errorf(codes.Unimplemented, err.Error()) 18 | } 19 | 20 | res := &pb.UserResponse{ 21 | User: &pb.User{ 22 | Id: user.ID.Hex(), 23 | Name: user.Name, 24 | Email: user.Email, 25 | Role: user.Role, 26 | CreatedAt: timestamppb.New(user.CreatedAt), 27 | UpdatedAt: timestamppb.New(user.UpdatedAt), 28 | }, 29 | } 30 | return res, nil 31 | } 32 | -------------------------------------------------------------------------------- /gapi/rpc_get_post.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/wpcodevo/golang-mongodb/pb" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/status" 10 | "google.golang.org/protobuf/types/known/timestamppb" 11 | ) 12 | 13 | func (postServer *PostServer) GetPost(ctx context.Context, req *pb.PostRequest) (*pb.PostResponse, error) { 14 | postId := req.GetId() 15 | 16 | post, err := postServer.postService.FindPostById(postId) 17 | if err != nil { 18 | if strings.Contains(err.Error(), "Id exists") { 19 | return nil, status.Errorf(codes.NotFound, err.Error()) 20 | 21 | } 22 | return nil, status.Errorf(codes.Internal, err.Error()) 23 | } 24 | 25 | res := &pb.PostResponse{ 26 | Post: &pb.Post{ 27 | Id: post.Id.Hex(), 28 | Title: post.Title, 29 | Content: post.Content, 30 | Image: post.Image, 31 | User: post.User, 32 | CreatedAt: timestamppb.New(post.CreateAt), 33 | UpdatedAt: timestamppb.New(post.UpdatedAt), 34 | }, 35 | } 36 | return res, nil 37 | } 38 | -------------------------------------------------------------------------------- /gapi/rpc_list_posts.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "github.com/wpcodevo/golang-mongodb/pb" 5 | "google.golang.org/grpc/codes" 6 | "google.golang.org/grpc/status" 7 | "google.golang.org/protobuf/types/known/timestamppb" 8 | ) 9 | 10 | func (postServer *PostServer) GetPosts(req *pb.GetPostsRequest, stream pb.PostService_GetPostsServer) error { 11 | var page = req.GetPage() 12 | var limit = req.GetLimit() 13 | 14 | posts, err := postServer.postService.FindPosts(int(page), int(limit)) 15 | if err != nil { 16 | return status.Errorf(codes.Internal, err.Error()) 17 | } 18 | 19 | for _, post := range posts { 20 | stream.Send(&pb.Post{ 21 | Id: post.Id.Hex(), 22 | Title: post.Title, 23 | Content: post.Content, 24 | Image: post.Image, 25 | CreatedAt: timestamppb.New(post.CreateAt), 26 | UpdatedAt: timestamppb.New(post.UpdatedAt), 27 | }) 28 | } 29 | 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /gapi/rpc_signin_user.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/wpcodevo/golang-mongodb/pb" 7 | "github.com/wpcodevo/golang-mongodb/utils" 8 | "go.mongodb.org/mongo-driver/mongo" 9 | "google.golang.org/grpc/codes" 10 | "google.golang.org/grpc/status" 11 | ) 12 | 13 | func (authServer *AuthServer) SignInUser(ctx context.Context, req *pb.SignInUserInput) (*pb.SignInUserResponse, error) { 14 | user, err := authServer.userService.FindUserByEmail(req.GetEmail()) 15 | if err != nil { 16 | if err == mongo.ErrNoDocuments { 17 | 18 | return nil, status.Errorf(codes.InvalidArgument, "Invalid email or password") 19 | 20 | } 21 | 22 | return nil, status.Errorf(codes.Internal, err.Error()) 23 | 24 | } 25 | 26 | if !user.Verified { 27 | 28 | return nil, status.Errorf(codes.PermissionDenied, "You are not verified, please verify your email to login") 29 | 30 | } 31 | 32 | if err := utils.VerifyPassword(user.Password, req.GetPassword()); err != nil { 33 | 34 | return nil, status.Errorf(codes.InvalidArgument, "Invalid email or Password") 35 | 36 | } 37 | 38 | // Generate Tokens 39 | access_token, err := utils.CreateToken(authServer.config.AccessTokenExpiresIn, user.ID, authServer.config.AccessTokenPrivateKey) 40 | if err != nil { 41 | 42 | return nil, status.Errorf(codes.PermissionDenied, err.Error()) 43 | 44 | } 45 | 46 | refresh_token, err := utils.CreateToken(authServer.config.RefreshTokenExpiresIn, user.ID, authServer.config.RefreshTokenPrivateKey) 47 | if err != nil { 48 | return nil, status.Errorf(codes.PermissionDenied, err.Error()) 49 | } 50 | 51 | res := &pb.SignInUserResponse{ 52 | Status: "success", 53 | AccessToken: access_token, 54 | RefreshToken: refresh_token, 55 | } 56 | 57 | return res, nil 58 | } 59 | -------------------------------------------------------------------------------- /gapi/rpc_signup_user.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/thanhpk/randstr" 8 | "github.com/wpcodevo/golang-mongodb/models" 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "github.com/wpcodevo/golang-mongodb/utils" 11 | "google.golang.org/grpc/codes" 12 | "google.golang.org/grpc/status" 13 | ) 14 | 15 | func (authServer *AuthServer) SignUpUser(ctx context.Context, req *pb.SignUpUserInput) (*pb.GenericResponse, error) { 16 | if req.GetPassword() != req.GetPasswordConfirm() { 17 | return nil, status.Errorf(codes.InvalidArgument, "passwords do not match") 18 | } 19 | 20 | user := models.SignUpInput{ 21 | Name: req.GetName(), 22 | Email: req.GetEmail(), 23 | Password: req.GetPassword(), 24 | PasswordConfirm: req.GetPasswordConfirm(), 25 | } 26 | 27 | newUser, err := authServer.authService.SignUpUser(&user) 28 | 29 | if err != nil { 30 | if strings.Contains(err.Error(), "email already exist") { 31 | return nil, status.Errorf(codes.AlreadyExists, "%s", err.Error()) 32 | 33 | } 34 | return nil, status.Errorf(codes.Internal, "%s", err.Error()) 35 | } 36 | 37 | // Generate Verification Code 38 | code := randstr.String(20) 39 | 40 | verificationCode := utils.Encode(code) 41 | 42 | updateData := &models.UpdateInput{ 43 | VerificationCode: verificationCode, 44 | } 45 | 46 | // Update User in Database 47 | authServer.userService.UpdateUserById(newUser.ID.Hex(), updateData) 48 | 49 | var firstName = newUser.Name 50 | 51 | if strings.Contains(firstName, " ") { 52 | firstName = strings.Split(firstName, " ")[0] 53 | } 54 | 55 | // 👇 Send Email 56 | emailData := utils.EmailData{ 57 | URL: authServer.config.Origin + "/verifyemail/" + code, 58 | FirstName: firstName, 59 | Subject: "Your account verification code", 60 | } 61 | 62 | err = utils.SendEmail(newUser, &emailData, "verificationCode.html") 63 | if err != nil { 64 | return nil, status.Errorf(codes.Internal, "There was an error sending email: %s", err.Error()) 65 | 66 | } 67 | 68 | message := "We sent an email with a verification code to " + newUser.Email 69 | 70 | res := &pb.GenericResponse{ 71 | Status: "success", 72 | Message: message, 73 | } 74 | return res, nil 75 | } 76 | -------------------------------------------------------------------------------- /gapi/rpc_update_post.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | "time" 7 | 8 | "github.com/wpcodevo/golang-mongodb/models" 9 | "github.com/wpcodevo/golang-mongodb/pb" 10 | "google.golang.org/grpc/codes" 11 | "google.golang.org/grpc/status" 12 | "google.golang.org/protobuf/types/known/timestamppb" 13 | ) 14 | 15 | func (postServer *PostServer) UpdatePost(ctx context.Context, req *pb.UpdatePostRequest) (*pb.PostResponse, error) { 16 | postId := req.GetId() 17 | 18 | post := &models.UpdatePost{ 19 | Title: req.GetTitle(), 20 | Content: req.GetContent(), 21 | Image: req.GetImage(), 22 | User: req.GetUser(), 23 | UpdatedAt: time.Now(), 24 | } 25 | 26 | updatedPost, err := postServer.postService.UpdatePost(postId, post) 27 | 28 | if err != nil { 29 | if strings.Contains(err.Error(), "Id exists") { 30 | return nil, status.Errorf(codes.NotFound, err.Error()) 31 | } 32 | return nil, status.Errorf(codes.Internal, err.Error()) 33 | } 34 | 35 | res := &pb.PostResponse{ 36 | Post: &pb.Post{ 37 | Id: updatedPost.Id.Hex(), 38 | Title: updatedPost.Title, 39 | Content: updatedPost.Content, 40 | Image: updatedPost.Image, 41 | User: updatedPost.User, 42 | CreatedAt: timestamppb.New(updatedPost.CreateAt), 43 | UpdatedAt: timestamppb.New(updatedPost.UpdatedAt), 44 | }, 45 | } 46 | return res, nil 47 | } 48 | -------------------------------------------------------------------------------- /gapi/rpc_verify_user.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/wpcodevo/golang-mongodb/pb" 8 | "github.com/wpcodevo/golang-mongodb/utils" 9 | "go.mongodb.org/mongo-driver/bson" 10 | "google.golang.org/grpc/codes" 11 | "google.golang.org/grpc/status" 12 | ) 13 | 14 | func (authServer *AuthServer) VerifyEmail(ctx context.Context, req *pb.VerifyEmailRequest) (*pb.GenericResponse, error) { 15 | code := req.GetVerificationCode() 16 | 17 | verificationCode := utils.Encode(code) 18 | 19 | query := bson.D{{Key: "verificationCode", Value: verificationCode}} 20 | update := bson.D{{Key: "$set", Value: bson.D{{Key: "verified", Value: true}, {Key: "updated_at", Value: time.Now()}}}, {Key: "$unset", Value: bson.D{{Key: "verificationCode", Value: ""}}}} 21 | result, err := authServer.userCollection.UpdateOne(ctx, query, update) 22 | if err != nil { 23 | return nil, status.Errorf(codes.Internal, err.Error()) 24 | } 25 | 26 | if result.MatchedCount == 0 { 27 | return nil, status.Errorf(codes.PermissionDenied, "Could not verify email address") 28 | } 29 | 30 | res := &pb.GenericResponse{ 31 | Status: "success", 32 | Message: "Email verified successfully", 33 | } 34 | return res, nil 35 | } 36 | -------------------------------------------------------------------------------- /gapi/user-server.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "github.com/wpcodevo/golang-mongodb/config" 5 | "github.com/wpcodevo/golang-mongodb/pb" 6 | "github.com/wpcodevo/golang-mongodb/services" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | ) 9 | 10 | type UserServer struct { 11 | pb.UnimplementedUserServiceServer 12 | config config.Config 13 | userService services.UserService 14 | userCollection *mongo.Collection 15 | } 16 | 17 | func NewGrpcUserServer(config config.Config, userService services.UserService, userCollection *mongo.Collection) (*UserServer, error) { 18 | userServer := &UserServer{ 19 | config: config, 20 | userService: userService, 21 | userCollection: userCollection, 22 | } 23 | 24 | return userServer, nil 25 | } 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wpcodevo/golang-mongodb 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gin-contrib/cors v1.3.1 7 | github.com/gin-gonic/gin v1.7.7 8 | github.com/go-redis/redis/v8 v8.11.5 9 | github.com/golang-jwt/jwt v3.2.2+incompatible 10 | github.com/k3a/html2text v1.0.8 11 | github.com/spf13/viper v1.11.0 12 | github.com/thanhpk/randstr v1.0.4 13 | go.mongodb.org/mongo-driver v1.9.1 14 | golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 15 | google.golang.org/grpc v1.45.0 16 | google.golang.org/protobuf v1.28.0 17 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 18 | ) 19 | 20 | require ( 21 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 22 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 23 | github.com/fsnotify/fsnotify v1.5.1 // indirect 24 | github.com/gin-contrib/sse v0.1.0 // indirect 25 | github.com/go-playground/locales v0.14.0 // indirect 26 | github.com/go-playground/universal-translator v0.18.0 // indirect 27 | github.com/go-playground/validator/v10 v10.11.0 // indirect 28 | github.com/go-stack/stack v1.8.0 // indirect 29 | github.com/golang/protobuf v1.5.2 // indirect 30 | github.com/golang/snappy v0.0.1 // indirect 31 | github.com/hashicorp/hcl v1.0.0 // indirect 32 | github.com/json-iterator/go v1.1.12 // indirect 33 | github.com/klauspost/compress v1.13.6 // indirect 34 | github.com/leodido/go-urn v1.2.1 // indirect 35 | github.com/magiconair/properties v1.8.6 // indirect 36 | github.com/mattn/go-isatty v0.0.14 // indirect 37 | github.com/mitchellh/mapstructure v1.4.3 // indirect 38 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 39 | github.com/modern-go/reflect2 v1.0.2 // indirect 40 | github.com/pelletier/go-toml v1.9.4 // indirect 41 | github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect 42 | github.com/pkg/errors v0.9.1 // indirect 43 | github.com/spf13/afero v1.8.2 // indirect 44 | github.com/spf13/cast v1.4.1 // indirect 45 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 46 | github.com/spf13/pflag v1.0.5 // indirect 47 | github.com/subosito/gotenv v1.2.0 // indirect 48 | github.com/ugorji/go/codec v1.2.7 // indirect 49 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 50 | github.com/xdg-go/scram v1.0.2 // indirect 51 | github.com/xdg-go/stringprep v1.0.2 // indirect 52 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect 53 | golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect 54 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect 55 | golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect 56 | golang.org/x/text v0.3.7 // indirect 57 | google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect 58 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 59 | gopkg.in/ini.v1 v1.66.4 // indirect 60 | gopkg.in/yaml.v2 v2.4.0 // indirect 61 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 62 | ) 63 | -------------------------------------------------------------------------------- /middleware/deserialize-user.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strings" 7 | 8 | "github.com/gin-gonic/gin" 9 | "github.com/wpcodevo/golang-mongodb/config" 10 | "github.com/wpcodevo/golang-mongodb/services" 11 | "github.com/wpcodevo/golang-mongodb/utils" 12 | ) 13 | 14 | func DeserializeUser(userService services.UserService) gin.HandlerFunc { 15 | return func(ctx *gin.Context) { 16 | var access_token string 17 | cookie, err := ctx.Cookie("access_token") 18 | 19 | authorizationHeader := ctx.Request.Header.Get("Authorization") 20 | fields := strings.Fields(authorizationHeader) 21 | 22 | if len(fields) != 0 && fields[0] == "Bearer" { 23 | access_token = fields[1] 24 | } else if err == nil { 25 | access_token = cookie 26 | } 27 | 28 | if access_token == "" { 29 | ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": "You are not logged in"}) 30 | return 31 | } 32 | 33 | config, _ := config.LoadConfig(".") 34 | sub, err := utils.ValidateToken(access_token, config.AccessTokenPublicKey) 35 | if err != nil { 36 | ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": err.Error()}) 37 | return 38 | } 39 | 40 | user, err := userService.FindUserById(fmt.Sprint(sub)) 41 | if err != nil { 42 | ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": "The user belonging to this token no logger exists"}) 43 | return 44 | } 45 | 46 | ctx.Set("currentUser", user) 47 | ctx.Next() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /models/post.model.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "go.mongodb.org/mongo-driver/bson/primitive" 7 | ) 8 | 9 | type CreatePostRequest struct { 10 | Title string `json:"title" bson:"title" binding:"required"` 11 | Content string `json:"content" bson:"content" binding:"required"` 12 | Image string `json:"image,omitempty" bson:"image,omitempty"` 13 | User string `json:"user" bson:"user" binding:"required"` 14 | CreateAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"` 15 | UpdatedAt time.Time `json:"updated_at,omitempty" bson:"updated_at,omitempty"` 16 | } 17 | 18 | type DBPost struct { 19 | Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` 20 | Title string `json:"title,omitempty" bson:"title,omitempty"` 21 | Content string `json:"content,omitempty" bson:"content,omitempty"` 22 | Image string `json:"image,omitempty" bson:"image,omitempty"` 23 | User string `json:"user,omitempty" bson:"user,omitempty"` 24 | CreateAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"` 25 | UpdatedAt time.Time `json:"updated_at,omitempty" bson:"updated_at,omitempty"` 26 | } 27 | 28 | type UpdatePost struct { 29 | Title string `json:"title,omitempty" bson:"title,omitempty"` 30 | Content string `json:"content,omitempty" bson:"content,omitempty"` 31 | Image string `json:"image,omitempty" bson:"image,omitempty"` 32 | User string `json:"user,omitempty" bson:"user,omitempty"` 33 | CreateAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"` 34 | UpdatedAt time.Time `json:"updated_at,omitempty" bson:"updated_at,omitempty"` 35 | } 36 | -------------------------------------------------------------------------------- /models/user.model.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "go.mongodb.org/mongo-driver/bson/primitive" 7 | ) 8 | 9 | // 👈 SignUpInput struct 10 | type SignUpInput struct { 11 | Name string `json:"name" bson:"name" binding:"required"` 12 | Email string `json:"email" bson:"email" binding:"required"` 13 | Password string `json:"password" bson:"password" binding:"required,min=8"` 14 | PasswordConfirm string `json:"passwordConfirm" bson:"passwordConfirm,omitempty" binding:"required"` 15 | Role string `json:"role" bson:"role"` 16 | VerificationCode string `json:"verificationCode,omitempty" bson:"verificationCode,omitempty"` 17 | ResetPasswordToken string `json:"resetPasswordToken,omitempty" bson:"resetPasswordToken,omitempty"` 18 | ResetPasswordAt time.Time `json:"resetPasswordAt,omitempty" bson:"resetPasswordAt,omitempty"` 19 | Verified bool `json:"verified" bson:"verified"` 20 | CreatedAt time.Time `json:"created_at" bson:"created_at"` 21 | UpdatedAt time.Time `json:"updated_at" bson:"updated_at"` 22 | } 23 | 24 | // 👈 SignInInput struct 25 | type SignInInput struct { 26 | Email string `json:"email" bson:"email" binding:"required"` 27 | Password string `json:"password" bson:"password" binding:"required"` 28 | } 29 | 30 | // 👈 DBResponse struct 31 | type DBResponse struct { 32 | ID primitive.ObjectID `json:"id" bson:"_id"` 33 | Name string `json:"name" bson:"name"` 34 | Email string `json:"email" bson:"email"` 35 | Password string `json:"password" bson:"password"` 36 | PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"` 37 | Role string `json:"role" bson:"role"` 38 | VerificationCode string `json:"verificationCode,omitempty" bson:"verificationCode"` 39 | ResetPasswordToken string `json:"resetPasswordToken,omitempty" bson:"resetPasswordToken,omitempty"` 40 | ResetPasswordAt time.Time `json:"resetPasswordAt,omitempty" bson:"resetPasswordAt,omitempty"` 41 | Verified bool `json:"verified" bson:"verified"` 42 | CreatedAt time.Time `json:"created_at" bson:"created_at"` 43 | UpdatedAt time.Time `json:"updated_at" bson:"updated_at"` 44 | } 45 | 46 | type UpdateInput struct { 47 | Name string `json:"name,omitempty" bson:"name,omitempty"` 48 | Email string `json:"email,omitempty" bson:"email,omitempty"` 49 | Password string `json:"password,omitempty" bson:"password,omitempty"` 50 | Role string `json:"role,omitempty" bson:"role,omitempty"` 51 | VerificationCode string `json:"verificationCode,omitempty" bson:"verificationCode,omitempty"` 52 | ResetPasswordToken string `json:"resetPasswordToken,omitempty" bson:"resetPasswordToken,omitempty"` 53 | ResetPasswordAt time.Time `json:"resetPasswordAt,omitempty" bson:"resetPasswordAt,omitempty"` 54 | Verified bool `json:"verified,omitempty" bson:"verified,omitempty"` 55 | CreatedAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"` 56 | UpdatedAt time.Time `json:"updated_at,omitempty" bson:"updated_at,omitempty"` 57 | } 58 | 59 | // 👈 UserResponse struct 60 | type UserResponse struct { 61 | ID primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` 62 | Name string `json:"name,omitempty" bson:"name,omitempty"` 63 | Email string `json:"email,omitempty" bson:"email,omitempty"` 64 | Role string `json:"role,omitempty" bson:"role,omitempty"` 65 | CreatedAt time.Time `json:"created_at" bson:"created_at"` 66 | UpdatedAt time.Time `json:"updated_at" bson:"updated_at"` 67 | } 68 | 69 | // 👈 ForgotPasswordInput struct 70 | type ForgotPasswordInput struct { 71 | Email string `json:"email" bson:"email" binding:"required"` 72 | } 73 | 74 | // 👈 ResetPasswordInput struct 75 | type ResetPasswordInput struct { 76 | Password string `json:"password" bson:"password"` 77 | PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"` 78 | } 79 | 80 | func FilteredResponse(user *DBResponse) UserResponse { 81 | return UserResponse{ 82 | ID: user.ID, 83 | Email: user.Email, 84 | Name: user.Name, 85 | Role: user.Role, 86 | CreatedAt: user.CreatedAt, 87 | UpdatedAt: user.UpdatedAt, 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /pb/auth_service.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: auth_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type VerifyEmailRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | VerificationCode string `protobuf:"bytes,1,opt,name=verificationCode,proto3" json:"verificationCode,omitempty"` 29 | } 30 | 31 | func (x *VerifyEmailRequest) Reset() { 32 | *x = VerifyEmailRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_auth_service_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *VerifyEmailRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*VerifyEmailRequest) ProtoMessage() {} 45 | 46 | func (x *VerifyEmailRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_auth_service_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use VerifyEmailRequest.ProtoReflect.Descriptor instead. 59 | func (*VerifyEmailRequest) Descriptor() ([]byte, []int) { 60 | return file_auth_service_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *VerifyEmailRequest) GetVerificationCode() string { 64 | if x != nil { 65 | return x.VerificationCode 66 | } 67 | return "" 68 | } 69 | 70 | var File_auth_service_proto protoreflect.FileDescriptor 71 | 72 | var file_auth_service_proto_rawDesc = []byte{ 73 | 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 74 | 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x69, 75 | 0x67, 0x6e, 0x69, 0x6e, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 76 | 0x15, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x5f, 0x75, 0x73, 0x65, 0x72, 77 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 78 | 0x74, 0x6f, 0x22, 0x40, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 79 | 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x76, 0x65, 0x72, 0x69, 80 | 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 81 | 0x28, 0x09, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 82 | 0x43, 0x6f, 0x64, 0x65, 0x32, 0xc2, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 83 | 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x55, 0x73, 84 | 0x65, 0x72, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x55, 0x73, 85 | 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 86 | 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 87 | 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x2e, 0x70, 88 | 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 89 | 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x55, 0x73, 0x65, 90 | 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0b, 0x56, 91 | 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 92 | 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 93 | 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 94 | 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 95 | 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 96 | 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 97 | 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 98 | } 99 | 100 | var ( 101 | file_auth_service_proto_rawDescOnce sync.Once 102 | file_auth_service_proto_rawDescData = file_auth_service_proto_rawDesc 103 | ) 104 | 105 | func file_auth_service_proto_rawDescGZIP() []byte { 106 | file_auth_service_proto_rawDescOnce.Do(func() { 107 | file_auth_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_service_proto_rawDescData) 108 | }) 109 | return file_auth_service_proto_rawDescData 110 | } 111 | 112 | var file_auth_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) 113 | var file_auth_service_proto_goTypes = []interface{}{ 114 | (*VerifyEmailRequest)(nil), // 0: pb.VerifyEmailRequest 115 | (*SignUpUserInput)(nil), // 1: pb.SignUpUserInput 116 | (*SignInUserInput)(nil), // 2: pb.SignInUserInput 117 | (*GenericResponse)(nil), // 3: pb.GenericResponse 118 | (*SignInUserResponse)(nil), // 4: pb.SignInUserResponse 119 | } 120 | var file_auth_service_proto_depIdxs = []int32{ 121 | 1, // 0: pb.AuthService.SignUpUser:input_type -> pb.SignUpUserInput 122 | 2, // 1: pb.AuthService.SignInUser:input_type -> pb.SignInUserInput 123 | 0, // 2: pb.AuthService.VerifyEmail:input_type -> pb.VerifyEmailRequest 124 | 3, // 3: pb.AuthService.SignUpUser:output_type -> pb.GenericResponse 125 | 4, // 4: pb.AuthService.SignInUser:output_type -> pb.SignInUserResponse 126 | 3, // 5: pb.AuthService.VerifyEmail:output_type -> pb.GenericResponse 127 | 3, // [3:6] is the sub-list for method output_type 128 | 0, // [0:3] is the sub-list for method input_type 129 | 0, // [0:0] is the sub-list for extension type_name 130 | 0, // [0:0] is the sub-list for extension extendee 131 | 0, // [0:0] is the sub-list for field type_name 132 | } 133 | 134 | func init() { file_auth_service_proto_init() } 135 | func file_auth_service_proto_init() { 136 | if File_auth_service_proto != nil { 137 | return 138 | } 139 | file_rpc_signin_user_proto_init() 140 | file_rpc_signup_user_proto_init() 141 | file_user_proto_init() 142 | if !protoimpl.UnsafeEnabled { 143 | file_auth_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 144 | switch v := v.(*VerifyEmailRequest); i { 145 | case 0: 146 | return &v.state 147 | case 1: 148 | return &v.sizeCache 149 | case 2: 150 | return &v.unknownFields 151 | default: 152 | return nil 153 | } 154 | } 155 | } 156 | type x struct{} 157 | out := protoimpl.TypeBuilder{ 158 | File: protoimpl.DescBuilder{ 159 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 160 | RawDescriptor: file_auth_service_proto_rawDesc, 161 | NumEnums: 0, 162 | NumMessages: 1, 163 | NumExtensions: 0, 164 | NumServices: 1, 165 | }, 166 | GoTypes: file_auth_service_proto_goTypes, 167 | DependencyIndexes: file_auth_service_proto_depIdxs, 168 | MessageInfos: file_auth_service_proto_msgTypes, 169 | }.Build() 170 | File_auth_service_proto = out.File 171 | file_auth_service_proto_rawDesc = nil 172 | file_auth_service_proto_goTypes = nil 173 | file_auth_service_proto_depIdxs = nil 174 | } 175 | -------------------------------------------------------------------------------- /pb/auth_service_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.2.0 4 | // - protoc v3.20.1 5 | // source: auth_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.32.0 or later. 19 | const _ = grpc.SupportPackageIsVersion7 20 | 21 | // AuthServiceClient is the client API for AuthService service. 22 | // 23 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 24 | type AuthServiceClient interface { 25 | SignUpUser(ctx context.Context, in *SignUpUserInput, opts ...grpc.CallOption) (*GenericResponse, error) 26 | SignInUser(ctx context.Context, in *SignInUserInput, opts ...grpc.CallOption) (*SignInUserResponse, error) 27 | VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*GenericResponse, error) 28 | } 29 | 30 | type authServiceClient struct { 31 | cc grpc.ClientConnInterface 32 | } 33 | 34 | func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { 35 | return &authServiceClient{cc} 36 | } 37 | 38 | func (c *authServiceClient) SignUpUser(ctx context.Context, in *SignUpUserInput, opts ...grpc.CallOption) (*GenericResponse, error) { 39 | out := new(GenericResponse) 40 | err := c.cc.Invoke(ctx, "/pb.AuthService/SignUpUser", in, out, opts...) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return out, nil 45 | } 46 | 47 | func (c *authServiceClient) SignInUser(ctx context.Context, in *SignInUserInput, opts ...grpc.CallOption) (*SignInUserResponse, error) { 48 | out := new(SignInUserResponse) 49 | err := c.cc.Invoke(ctx, "/pb.AuthService/SignInUser", in, out, opts...) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return out, nil 54 | } 55 | 56 | func (c *authServiceClient) VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*GenericResponse, error) { 57 | out := new(GenericResponse) 58 | err := c.cc.Invoke(ctx, "/pb.AuthService/VerifyEmail", in, out, opts...) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return out, nil 63 | } 64 | 65 | // AuthServiceServer is the server API for AuthService service. 66 | // All implementations must embed UnimplementedAuthServiceServer 67 | // for forward compatibility 68 | type AuthServiceServer interface { 69 | SignUpUser(context.Context, *SignUpUserInput) (*GenericResponse, error) 70 | SignInUser(context.Context, *SignInUserInput) (*SignInUserResponse, error) 71 | VerifyEmail(context.Context, *VerifyEmailRequest) (*GenericResponse, error) 72 | mustEmbedUnimplementedAuthServiceServer() 73 | } 74 | 75 | // UnimplementedAuthServiceServer must be embedded to have forward compatible implementations. 76 | type UnimplementedAuthServiceServer struct { 77 | } 78 | 79 | func (UnimplementedAuthServiceServer) SignUpUser(context.Context, *SignUpUserInput) (*GenericResponse, error) { 80 | return nil, status.Errorf(codes.Unimplemented, "method SignUpUser not implemented") 81 | } 82 | func (UnimplementedAuthServiceServer) SignInUser(context.Context, *SignInUserInput) (*SignInUserResponse, error) { 83 | return nil, status.Errorf(codes.Unimplemented, "method SignInUser not implemented") 84 | } 85 | func (UnimplementedAuthServiceServer) VerifyEmail(context.Context, *VerifyEmailRequest) (*GenericResponse, error) { 86 | return nil, status.Errorf(codes.Unimplemented, "method VerifyEmail not implemented") 87 | } 88 | func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} 89 | 90 | // UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. 91 | // Use of this interface is not recommended, as added methods to AuthServiceServer will 92 | // result in compilation errors. 93 | type UnsafeAuthServiceServer interface { 94 | mustEmbedUnimplementedAuthServiceServer() 95 | } 96 | 97 | func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { 98 | s.RegisterService(&AuthService_ServiceDesc, srv) 99 | } 100 | 101 | func _AuthService_SignUpUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 102 | in := new(SignUpUserInput) 103 | if err := dec(in); err != nil { 104 | return nil, err 105 | } 106 | if interceptor == nil { 107 | return srv.(AuthServiceServer).SignUpUser(ctx, in) 108 | } 109 | info := &grpc.UnaryServerInfo{ 110 | Server: srv, 111 | FullMethod: "/pb.AuthService/SignUpUser", 112 | } 113 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 114 | return srv.(AuthServiceServer).SignUpUser(ctx, req.(*SignUpUserInput)) 115 | } 116 | return interceptor(ctx, in, info, handler) 117 | } 118 | 119 | func _AuthService_SignInUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 120 | in := new(SignInUserInput) 121 | if err := dec(in); err != nil { 122 | return nil, err 123 | } 124 | if interceptor == nil { 125 | return srv.(AuthServiceServer).SignInUser(ctx, in) 126 | } 127 | info := &grpc.UnaryServerInfo{ 128 | Server: srv, 129 | FullMethod: "/pb.AuthService/SignInUser", 130 | } 131 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 132 | return srv.(AuthServiceServer).SignInUser(ctx, req.(*SignInUserInput)) 133 | } 134 | return interceptor(ctx, in, info, handler) 135 | } 136 | 137 | func _AuthService_VerifyEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 138 | in := new(VerifyEmailRequest) 139 | if err := dec(in); err != nil { 140 | return nil, err 141 | } 142 | if interceptor == nil { 143 | return srv.(AuthServiceServer).VerifyEmail(ctx, in) 144 | } 145 | info := &grpc.UnaryServerInfo{ 146 | Server: srv, 147 | FullMethod: "/pb.AuthService/VerifyEmail", 148 | } 149 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 150 | return srv.(AuthServiceServer).VerifyEmail(ctx, req.(*VerifyEmailRequest)) 151 | } 152 | return interceptor(ctx, in, info, handler) 153 | } 154 | 155 | // AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. 156 | // It's only intended for direct use with grpc.RegisterService, 157 | // and not to be introspected or modified (even as a copy) 158 | var AuthService_ServiceDesc = grpc.ServiceDesc{ 159 | ServiceName: "pb.AuthService", 160 | HandlerType: (*AuthServiceServer)(nil), 161 | Methods: []grpc.MethodDesc{ 162 | { 163 | MethodName: "SignUpUser", 164 | Handler: _AuthService_SignUpUser_Handler, 165 | }, 166 | { 167 | MethodName: "SignInUser", 168 | Handler: _AuthService_SignInUser_Handler, 169 | }, 170 | { 171 | MethodName: "VerifyEmail", 172 | Handler: _AuthService_VerifyEmail_Handler, 173 | }, 174 | }, 175 | Streams: []grpc.StreamDesc{}, 176 | Metadata: "auth_service.proto", 177 | } 178 | -------------------------------------------------------------------------------- /pb/post.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: post.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | timestamppb "google.golang.org/protobuf/types/known/timestamppb" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type Post struct { 25 | state protoimpl.MessageState 26 | sizeCache protoimpl.SizeCache 27 | unknownFields protoimpl.UnknownFields 28 | 29 | Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` 30 | Title string `protobuf:"bytes,2,opt,name=Title,proto3" json:"Title,omitempty"` 31 | Content string `protobuf:"bytes,3,opt,name=Content,proto3" json:"Content,omitempty"` 32 | Image string `protobuf:"bytes,4,opt,name=Image,proto3" json:"Image,omitempty"` 33 | User string `protobuf:"bytes,5,opt,name=User,proto3" json:"User,omitempty"` 34 | CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` 35 | UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` 36 | } 37 | 38 | func (x *Post) Reset() { 39 | *x = Post{} 40 | if protoimpl.UnsafeEnabled { 41 | mi := &file_post_proto_msgTypes[0] 42 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 43 | ms.StoreMessageInfo(mi) 44 | } 45 | } 46 | 47 | func (x *Post) String() string { 48 | return protoimpl.X.MessageStringOf(x) 49 | } 50 | 51 | func (*Post) ProtoMessage() {} 52 | 53 | func (x *Post) ProtoReflect() protoreflect.Message { 54 | mi := &file_post_proto_msgTypes[0] 55 | if protoimpl.UnsafeEnabled && x != nil { 56 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 57 | if ms.LoadMessageInfo() == nil { 58 | ms.StoreMessageInfo(mi) 59 | } 60 | return ms 61 | } 62 | return mi.MessageOf(x) 63 | } 64 | 65 | // Deprecated: Use Post.ProtoReflect.Descriptor instead. 66 | func (*Post) Descriptor() ([]byte, []int) { 67 | return file_post_proto_rawDescGZIP(), []int{0} 68 | } 69 | 70 | func (x *Post) GetId() string { 71 | if x != nil { 72 | return x.Id 73 | } 74 | return "" 75 | } 76 | 77 | func (x *Post) GetTitle() string { 78 | if x != nil { 79 | return x.Title 80 | } 81 | return "" 82 | } 83 | 84 | func (x *Post) GetContent() string { 85 | if x != nil { 86 | return x.Content 87 | } 88 | return "" 89 | } 90 | 91 | func (x *Post) GetImage() string { 92 | if x != nil { 93 | return x.Image 94 | } 95 | return "" 96 | } 97 | 98 | func (x *Post) GetUser() string { 99 | if x != nil { 100 | return x.User 101 | } 102 | return "" 103 | } 104 | 105 | func (x *Post) GetCreatedAt() *timestamppb.Timestamp { 106 | if x != nil { 107 | return x.CreatedAt 108 | } 109 | return nil 110 | } 111 | 112 | func (x *Post) GetUpdatedAt() *timestamppb.Timestamp { 113 | if x != nil { 114 | return x.UpdatedAt 115 | } 116 | return nil 117 | } 118 | 119 | type PostResponse struct { 120 | state protoimpl.MessageState 121 | sizeCache protoimpl.SizeCache 122 | unknownFields protoimpl.UnknownFields 123 | 124 | Post *Post `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"` 125 | } 126 | 127 | func (x *PostResponse) Reset() { 128 | *x = PostResponse{} 129 | if protoimpl.UnsafeEnabled { 130 | mi := &file_post_proto_msgTypes[1] 131 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 132 | ms.StoreMessageInfo(mi) 133 | } 134 | } 135 | 136 | func (x *PostResponse) String() string { 137 | return protoimpl.X.MessageStringOf(x) 138 | } 139 | 140 | func (*PostResponse) ProtoMessage() {} 141 | 142 | func (x *PostResponse) ProtoReflect() protoreflect.Message { 143 | mi := &file_post_proto_msgTypes[1] 144 | if protoimpl.UnsafeEnabled && x != nil { 145 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 146 | if ms.LoadMessageInfo() == nil { 147 | ms.StoreMessageInfo(mi) 148 | } 149 | return ms 150 | } 151 | return mi.MessageOf(x) 152 | } 153 | 154 | // Deprecated: Use PostResponse.ProtoReflect.Descriptor instead. 155 | func (*PostResponse) Descriptor() ([]byte, []int) { 156 | return file_post_proto_rawDescGZIP(), []int{1} 157 | } 158 | 159 | func (x *PostResponse) GetPost() *Post { 160 | if x != nil { 161 | return x.Post 162 | } 163 | return nil 164 | } 165 | 166 | var File_post_proto protoreflect.FileDescriptor 167 | 168 | var file_post_proto_rawDesc = []byte{ 169 | 0x0a, 0x0a, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 170 | 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 171 | 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 172 | 0x6f, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 173 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x69, 174 | 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 175 | 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 176 | 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6d, 177 | 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 178 | 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 179 | 0x55, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 180 | 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 181 | 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 182 | 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 183 | 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 184 | 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 185 | 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 186 | 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x2c, 0x0a, 0x0c, 0x50, 0x6f, 187 | 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x04, 0x70, 0x6f, 188 | 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 189 | 0x73, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 190 | 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 191 | 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 192 | 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 193 | } 194 | 195 | var ( 196 | file_post_proto_rawDescOnce sync.Once 197 | file_post_proto_rawDescData = file_post_proto_rawDesc 198 | ) 199 | 200 | func file_post_proto_rawDescGZIP() []byte { 201 | file_post_proto_rawDescOnce.Do(func() { 202 | file_post_proto_rawDescData = protoimpl.X.CompressGZIP(file_post_proto_rawDescData) 203 | }) 204 | return file_post_proto_rawDescData 205 | } 206 | 207 | var file_post_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 208 | var file_post_proto_goTypes = []interface{}{ 209 | (*Post)(nil), // 0: pb.Post 210 | (*PostResponse)(nil), // 1: pb.PostResponse 211 | (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp 212 | } 213 | var file_post_proto_depIdxs = []int32{ 214 | 2, // 0: pb.Post.created_at:type_name -> google.protobuf.Timestamp 215 | 2, // 1: pb.Post.updated_at:type_name -> google.protobuf.Timestamp 216 | 0, // 2: pb.PostResponse.post:type_name -> pb.Post 217 | 3, // [3:3] is the sub-list for method output_type 218 | 3, // [3:3] is the sub-list for method input_type 219 | 3, // [3:3] is the sub-list for extension type_name 220 | 3, // [3:3] is the sub-list for extension extendee 221 | 0, // [0:3] is the sub-list for field type_name 222 | } 223 | 224 | func init() { file_post_proto_init() } 225 | func file_post_proto_init() { 226 | if File_post_proto != nil { 227 | return 228 | } 229 | if !protoimpl.UnsafeEnabled { 230 | file_post_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 231 | switch v := v.(*Post); i { 232 | case 0: 233 | return &v.state 234 | case 1: 235 | return &v.sizeCache 236 | case 2: 237 | return &v.unknownFields 238 | default: 239 | return nil 240 | } 241 | } 242 | file_post_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 243 | switch v := v.(*PostResponse); i { 244 | case 0: 245 | return &v.state 246 | case 1: 247 | return &v.sizeCache 248 | case 2: 249 | return &v.unknownFields 250 | default: 251 | return nil 252 | } 253 | } 254 | } 255 | type x struct{} 256 | out := protoimpl.TypeBuilder{ 257 | File: protoimpl.DescBuilder{ 258 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 259 | RawDescriptor: file_post_proto_rawDesc, 260 | NumEnums: 0, 261 | NumMessages: 2, 262 | NumExtensions: 0, 263 | NumServices: 0, 264 | }, 265 | GoTypes: file_post_proto_goTypes, 266 | DependencyIndexes: file_post_proto_depIdxs, 267 | MessageInfos: file_post_proto_msgTypes, 268 | }.Build() 269 | File_post_proto = out.File 270 | file_post_proto_rawDesc = nil 271 | file_post_proto_goTypes = nil 272 | file_post_proto_depIdxs = nil 273 | } 274 | -------------------------------------------------------------------------------- /pb/post_service.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: post_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type GetPostsRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Page *int64 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"` 29 | Limit *int64 `protobuf:"varint,2,opt,name=limit,proto3,oneof" json:"limit,omitempty"` 30 | } 31 | 32 | func (x *GetPostsRequest) Reset() { 33 | *x = GetPostsRequest{} 34 | if protoimpl.UnsafeEnabled { 35 | mi := &file_post_service_proto_msgTypes[0] 36 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 37 | ms.StoreMessageInfo(mi) 38 | } 39 | } 40 | 41 | func (x *GetPostsRequest) String() string { 42 | return protoimpl.X.MessageStringOf(x) 43 | } 44 | 45 | func (*GetPostsRequest) ProtoMessage() {} 46 | 47 | func (x *GetPostsRequest) ProtoReflect() protoreflect.Message { 48 | mi := &file_post_service_proto_msgTypes[0] 49 | if protoimpl.UnsafeEnabled && x != nil { 50 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 51 | if ms.LoadMessageInfo() == nil { 52 | ms.StoreMessageInfo(mi) 53 | } 54 | return ms 55 | } 56 | return mi.MessageOf(x) 57 | } 58 | 59 | // Deprecated: Use GetPostsRequest.ProtoReflect.Descriptor instead. 60 | func (*GetPostsRequest) Descriptor() ([]byte, []int) { 61 | return file_post_service_proto_rawDescGZIP(), []int{0} 62 | } 63 | 64 | func (x *GetPostsRequest) GetPage() int64 { 65 | if x != nil && x.Page != nil { 66 | return *x.Page 67 | } 68 | return 0 69 | } 70 | 71 | func (x *GetPostsRequest) GetLimit() int64 { 72 | if x != nil && x.Limit != nil { 73 | return *x.Limit 74 | } 75 | return 0 76 | } 77 | 78 | type PostRequest struct { 79 | state protoimpl.MessageState 80 | sizeCache protoimpl.SizeCache 81 | unknownFields protoimpl.UnknownFields 82 | 83 | Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` 84 | } 85 | 86 | func (x *PostRequest) Reset() { 87 | *x = PostRequest{} 88 | if protoimpl.UnsafeEnabled { 89 | mi := &file_post_service_proto_msgTypes[1] 90 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 91 | ms.StoreMessageInfo(mi) 92 | } 93 | } 94 | 95 | func (x *PostRequest) String() string { 96 | return protoimpl.X.MessageStringOf(x) 97 | } 98 | 99 | func (*PostRequest) ProtoMessage() {} 100 | 101 | func (x *PostRequest) ProtoReflect() protoreflect.Message { 102 | mi := &file_post_service_proto_msgTypes[1] 103 | if protoimpl.UnsafeEnabled && x != nil { 104 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 105 | if ms.LoadMessageInfo() == nil { 106 | ms.StoreMessageInfo(mi) 107 | } 108 | return ms 109 | } 110 | return mi.MessageOf(x) 111 | } 112 | 113 | // Deprecated: Use PostRequest.ProtoReflect.Descriptor instead. 114 | func (*PostRequest) Descriptor() ([]byte, []int) { 115 | return file_post_service_proto_rawDescGZIP(), []int{1} 116 | } 117 | 118 | func (x *PostRequest) GetId() string { 119 | if x != nil { 120 | return x.Id 121 | } 122 | return "" 123 | } 124 | 125 | type DeletePostResponse struct { 126 | state protoimpl.MessageState 127 | sizeCache protoimpl.SizeCache 128 | unknownFields protoimpl.UnknownFields 129 | 130 | Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` 131 | } 132 | 133 | func (x *DeletePostResponse) Reset() { 134 | *x = DeletePostResponse{} 135 | if protoimpl.UnsafeEnabled { 136 | mi := &file_post_service_proto_msgTypes[2] 137 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 138 | ms.StoreMessageInfo(mi) 139 | } 140 | } 141 | 142 | func (x *DeletePostResponse) String() string { 143 | return protoimpl.X.MessageStringOf(x) 144 | } 145 | 146 | func (*DeletePostResponse) ProtoMessage() {} 147 | 148 | func (x *DeletePostResponse) ProtoReflect() protoreflect.Message { 149 | mi := &file_post_service_proto_msgTypes[2] 150 | if protoimpl.UnsafeEnabled && x != nil { 151 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 152 | if ms.LoadMessageInfo() == nil { 153 | ms.StoreMessageInfo(mi) 154 | } 155 | return ms 156 | } 157 | return mi.MessageOf(x) 158 | } 159 | 160 | // Deprecated: Use DeletePostResponse.ProtoReflect.Descriptor instead. 161 | func (*DeletePostResponse) Descriptor() ([]byte, []int) { 162 | return file_post_service_proto_rawDescGZIP(), []int{2} 163 | } 164 | 165 | func (x *DeletePostResponse) GetSuccess() bool { 166 | if x != nil { 167 | return x.Success 168 | } 169 | return false 170 | } 171 | 172 | var File_post_service_proto protoreflect.FileDescriptor 173 | 174 | var file_post_service_proto_rawDesc = []byte{ 175 | 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 176 | 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0a, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 177 | 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 178 | 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x72, 0x70, 0x63, 179 | 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 180 | 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x52, 0x65, 181 | 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 182 | 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 183 | 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 184 | 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 185 | 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x1d, 0x0a, 0x0b, 186 | 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 187 | 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x44, 188 | 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 189 | 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 190 | 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x32, 0x97, 0x02, 0x0a, 0x0b, 191 | 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x43, 192 | 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x43, 193 | 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 194 | 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 195 | 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 196 | 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 197 | 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 198 | 0x73, 0x65, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x73, 199 | 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x52, 0x65, 200 | 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 201 | 0x00, 0x30, 0x01, 0x12, 0x37, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 202 | 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 203 | 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 204 | 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0a, 205 | 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 206 | 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 207 | 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 208 | 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 209 | 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 0x67, 0x6f, 0x6c, 210 | 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 0x62, 0x62, 0x06, 211 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 212 | } 213 | 214 | var ( 215 | file_post_service_proto_rawDescOnce sync.Once 216 | file_post_service_proto_rawDescData = file_post_service_proto_rawDesc 217 | ) 218 | 219 | func file_post_service_proto_rawDescGZIP() []byte { 220 | file_post_service_proto_rawDescOnce.Do(func() { 221 | file_post_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_post_service_proto_rawDescData) 222 | }) 223 | return file_post_service_proto_rawDescData 224 | } 225 | 226 | var file_post_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 227 | var file_post_service_proto_goTypes = []interface{}{ 228 | (*GetPostsRequest)(nil), // 0: pb.GetPostsRequest 229 | (*PostRequest)(nil), // 1: pb.PostRequest 230 | (*DeletePostResponse)(nil), // 2: pb.DeletePostResponse 231 | (*CreatePostRequest)(nil), // 3: pb.CreatePostRequest 232 | (*UpdatePostRequest)(nil), // 4: pb.UpdatePostRequest 233 | (*PostResponse)(nil), // 5: pb.PostResponse 234 | (*Post)(nil), // 6: pb.Post 235 | } 236 | var file_post_service_proto_depIdxs = []int32{ 237 | 3, // 0: pb.PostService.CreatePost:input_type -> pb.CreatePostRequest 238 | 1, // 1: pb.PostService.GetPost:input_type -> pb.PostRequest 239 | 0, // 2: pb.PostService.GetPosts:input_type -> pb.GetPostsRequest 240 | 4, // 3: pb.PostService.UpdatePost:input_type -> pb.UpdatePostRequest 241 | 1, // 4: pb.PostService.DeletePost:input_type -> pb.PostRequest 242 | 5, // 5: pb.PostService.CreatePost:output_type -> pb.PostResponse 243 | 5, // 6: pb.PostService.GetPost:output_type -> pb.PostResponse 244 | 6, // 7: pb.PostService.GetPosts:output_type -> pb.Post 245 | 5, // 8: pb.PostService.UpdatePost:output_type -> pb.PostResponse 246 | 2, // 9: pb.PostService.DeletePost:output_type -> pb.DeletePostResponse 247 | 5, // [5:10] is the sub-list for method output_type 248 | 0, // [0:5] is the sub-list for method input_type 249 | 0, // [0:0] is the sub-list for extension type_name 250 | 0, // [0:0] is the sub-list for extension extendee 251 | 0, // [0:0] is the sub-list for field type_name 252 | } 253 | 254 | func init() { file_post_service_proto_init() } 255 | func file_post_service_proto_init() { 256 | if File_post_service_proto != nil { 257 | return 258 | } 259 | file_post_proto_init() 260 | file_rpc_create_post_proto_init() 261 | file_rpc_update_post_proto_init() 262 | if !protoimpl.UnsafeEnabled { 263 | file_post_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 264 | switch v := v.(*GetPostsRequest); i { 265 | case 0: 266 | return &v.state 267 | case 1: 268 | return &v.sizeCache 269 | case 2: 270 | return &v.unknownFields 271 | default: 272 | return nil 273 | } 274 | } 275 | file_post_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 276 | switch v := v.(*PostRequest); i { 277 | case 0: 278 | return &v.state 279 | case 1: 280 | return &v.sizeCache 281 | case 2: 282 | return &v.unknownFields 283 | default: 284 | return nil 285 | } 286 | } 287 | file_post_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 288 | switch v := v.(*DeletePostResponse); i { 289 | case 0: 290 | return &v.state 291 | case 1: 292 | return &v.sizeCache 293 | case 2: 294 | return &v.unknownFields 295 | default: 296 | return nil 297 | } 298 | } 299 | } 300 | file_post_service_proto_msgTypes[0].OneofWrappers = []interface{}{} 301 | type x struct{} 302 | out := protoimpl.TypeBuilder{ 303 | File: protoimpl.DescBuilder{ 304 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 305 | RawDescriptor: file_post_service_proto_rawDesc, 306 | NumEnums: 0, 307 | NumMessages: 3, 308 | NumExtensions: 0, 309 | NumServices: 1, 310 | }, 311 | GoTypes: file_post_service_proto_goTypes, 312 | DependencyIndexes: file_post_service_proto_depIdxs, 313 | MessageInfos: file_post_service_proto_msgTypes, 314 | }.Build() 315 | File_post_service_proto = out.File 316 | file_post_service_proto_rawDesc = nil 317 | file_post_service_proto_goTypes = nil 318 | file_post_service_proto_depIdxs = nil 319 | } 320 | -------------------------------------------------------------------------------- /pb/post_service_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.2.0 4 | // - protoc v3.20.1 5 | // source: post_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.32.0 or later. 19 | const _ = grpc.SupportPackageIsVersion7 20 | 21 | // PostServiceClient is the client API for PostService service. 22 | // 23 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 24 | type PostServiceClient interface { 25 | CreatePost(ctx context.Context, in *CreatePostRequest, opts ...grpc.CallOption) (*PostResponse, error) 26 | GetPost(ctx context.Context, in *PostRequest, opts ...grpc.CallOption) (*PostResponse, error) 27 | GetPosts(ctx context.Context, in *GetPostsRequest, opts ...grpc.CallOption) (PostService_GetPostsClient, error) 28 | UpdatePost(ctx context.Context, in *UpdatePostRequest, opts ...grpc.CallOption) (*PostResponse, error) 29 | DeletePost(ctx context.Context, in *PostRequest, opts ...grpc.CallOption) (*DeletePostResponse, error) 30 | } 31 | 32 | type postServiceClient struct { 33 | cc grpc.ClientConnInterface 34 | } 35 | 36 | func NewPostServiceClient(cc grpc.ClientConnInterface) PostServiceClient { 37 | return &postServiceClient{cc} 38 | } 39 | 40 | func (c *postServiceClient) CreatePost(ctx context.Context, in *CreatePostRequest, opts ...grpc.CallOption) (*PostResponse, error) { 41 | out := new(PostResponse) 42 | err := c.cc.Invoke(ctx, "/pb.PostService/CreatePost", in, out, opts...) 43 | if err != nil { 44 | return nil, err 45 | } 46 | return out, nil 47 | } 48 | 49 | func (c *postServiceClient) GetPost(ctx context.Context, in *PostRequest, opts ...grpc.CallOption) (*PostResponse, error) { 50 | out := new(PostResponse) 51 | err := c.cc.Invoke(ctx, "/pb.PostService/GetPost", in, out, opts...) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return out, nil 56 | } 57 | 58 | func (c *postServiceClient) GetPosts(ctx context.Context, in *GetPostsRequest, opts ...grpc.CallOption) (PostService_GetPostsClient, error) { 59 | stream, err := c.cc.NewStream(ctx, &PostService_ServiceDesc.Streams[0], "/pb.PostService/GetPosts", opts...) 60 | if err != nil { 61 | return nil, err 62 | } 63 | x := &postServiceGetPostsClient{stream} 64 | if err := x.ClientStream.SendMsg(in); err != nil { 65 | return nil, err 66 | } 67 | if err := x.ClientStream.CloseSend(); err != nil { 68 | return nil, err 69 | } 70 | return x, nil 71 | } 72 | 73 | type PostService_GetPostsClient interface { 74 | Recv() (*Post, error) 75 | grpc.ClientStream 76 | } 77 | 78 | type postServiceGetPostsClient struct { 79 | grpc.ClientStream 80 | } 81 | 82 | func (x *postServiceGetPostsClient) Recv() (*Post, error) { 83 | m := new(Post) 84 | if err := x.ClientStream.RecvMsg(m); err != nil { 85 | return nil, err 86 | } 87 | return m, nil 88 | } 89 | 90 | func (c *postServiceClient) UpdatePost(ctx context.Context, in *UpdatePostRequest, opts ...grpc.CallOption) (*PostResponse, error) { 91 | out := new(PostResponse) 92 | err := c.cc.Invoke(ctx, "/pb.PostService/UpdatePost", in, out, opts...) 93 | if err != nil { 94 | return nil, err 95 | } 96 | return out, nil 97 | } 98 | 99 | func (c *postServiceClient) DeletePost(ctx context.Context, in *PostRequest, opts ...grpc.CallOption) (*DeletePostResponse, error) { 100 | out := new(DeletePostResponse) 101 | err := c.cc.Invoke(ctx, "/pb.PostService/DeletePost", in, out, opts...) 102 | if err != nil { 103 | return nil, err 104 | } 105 | return out, nil 106 | } 107 | 108 | // PostServiceServer is the server API for PostService service. 109 | // All implementations must embed UnimplementedPostServiceServer 110 | // for forward compatibility 111 | type PostServiceServer interface { 112 | CreatePost(context.Context, *CreatePostRequest) (*PostResponse, error) 113 | GetPost(context.Context, *PostRequest) (*PostResponse, error) 114 | GetPosts(*GetPostsRequest, PostService_GetPostsServer) error 115 | UpdatePost(context.Context, *UpdatePostRequest) (*PostResponse, error) 116 | DeletePost(context.Context, *PostRequest) (*DeletePostResponse, error) 117 | mustEmbedUnimplementedPostServiceServer() 118 | } 119 | 120 | // UnimplementedPostServiceServer must be embedded to have forward compatible implementations. 121 | type UnimplementedPostServiceServer struct { 122 | } 123 | 124 | func (UnimplementedPostServiceServer) CreatePost(context.Context, *CreatePostRequest) (*PostResponse, error) { 125 | return nil, status.Errorf(codes.Unimplemented, "method CreatePost not implemented") 126 | } 127 | func (UnimplementedPostServiceServer) GetPost(context.Context, *PostRequest) (*PostResponse, error) { 128 | return nil, status.Errorf(codes.Unimplemented, "method GetPost not implemented") 129 | } 130 | func (UnimplementedPostServiceServer) GetPosts(*GetPostsRequest, PostService_GetPostsServer) error { 131 | return status.Errorf(codes.Unimplemented, "method GetPosts not implemented") 132 | } 133 | func (UnimplementedPostServiceServer) UpdatePost(context.Context, *UpdatePostRequest) (*PostResponse, error) { 134 | return nil, status.Errorf(codes.Unimplemented, "method UpdatePost not implemented") 135 | } 136 | func (UnimplementedPostServiceServer) DeletePost(context.Context, *PostRequest) (*DeletePostResponse, error) { 137 | return nil, status.Errorf(codes.Unimplemented, "method DeletePost not implemented") 138 | } 139 | func (UnimplementedPostServiceServer) mustEmbedUnimplementedPostServiceServer() {} 140 | 141 | // UnsafePostServiceServer may be embedded to opt out of forward compatibility for this service. 142 | // Use of this interface is not recommended, as added methods to PostServiceServer will 143 | // result in compilation errors. 144 | type UnsafePostServiceServer interface { 145 | mustEmbedUnimplementedPostServiceServer() 146 | } 147 | 148 | func RegisterPostServiceServer(s grpc.ServiceRegistrar, srv PostServiceServer) { 149 | s.RegisterService(&PostService_ServiceDesc, srv) 150 | } 151 | 152 | func _PostService_CreatePost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 153 | in := new(CreatePostRequest) 154 | if err := dec(in); err != nil { 155 | return nil, err 156 | } 157 | if interceptor == nil { 158 | return srv.(PostServiceServer).CreatePost(ctx, in) 159 | } 160 | info := &grpc.UnaryServerInfo{ 161 | Server: srv, 162 | FullMethod: "/pb.PostService/CreatePost", 163 | } 164 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 165 | return srv.(PostServiceServer).CreatePost(ctx, req.(*CreatePostRequest)) 166 | } 167 | return interceptor(ctx, in, info, handler) 168 | } 169 | 170 | func _PostService_GetPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 171 | in := new(PostRequest) 172 | if err := dec(in); err != nil { 173 | return nil, err 174 | } 175 | if interceptor == nil { 176 | return srv.(PostServiceServer).GetPost(ctx, in) 177 | } 178 | info := &grpc.UnaryServerInfo{ 179 | Server: srv, 180 | FullMethod: "/pb.PostService/GetPost", 181 | } 182 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 183 | return srv.(PostServiceServer).GetPost(ctx, req.(*PostRequest)) 184 | } 185 | return interceptor(ctx, in, info, handler) 186 | } 187 | 188 | func _PostService_GetPosts_Handler(srv interface{}, stream grpc.ServerStream) error { 189 | m := new(GetPostsRequest) 190 | if err := stream.RecvMsg(m); err != nil { 191 | return err 192 | } 193 | return srv.(PostServiceServer).GetPosts(m, &postServiceGetPostsServer{stream}) 194 | } 195 | 196 | type PostService_GetPostsServer interface { 197 | Send(*Post) error 198 | grpc.ServerStream 199 | } 200 | 201 | type postServiceGetPostsServer struct { 202 | grpc.ServerStream 203 | } 204 | 205 | func (x *postServiceGetPostsServer) Send(m *Post) error { 206 | return x.ServerStream.SendMsg(m) 207 | } 208 | 209 | func _PostService_UpdatePost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 210 | in := new(UpdatePostRequest) 211 | if err := dec(in); err != nil { 212 | return nil, err 213 | } 214 | if interceptor == nil { 215 | return srv.(PostServiceServer).UpdatePost(ctx, in) 216 | } 217 | info := &grpc.UnaryServerInfo{ 218 | Server: srv, 219 | FullMethod: "/pb.PostService/UpdatePost", 220 | } 221 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 222 | return srv.(PostServiceServer).UpdatePost(ctx, req.(*UpdatePostRequest)) 223 | } 224 | return interceptor(ctx, in, info, handler) 225 | } 226 | 227 | func _PostService_DeletePost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 228 | in := new(PostRequest) 229 | if err := dec(in); err != nil { 230 | return nil, err 231 | } 232 | if interceptor == nil { 233 | return srv.(PostServiceServer).DeletePost(ctx, in) 234 | } 235 | info := &grpc.UnaryServerInfo{ 236 | Server: srv, 237 | FullMethod: "/pb.PostService/DeletePost", 238 | } 239 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 240 | return srv.(PostServiceServer).DeletePost(ctx, req.(*PostRequest)) 241 | } 242 | return interceptor(ctx, in, info, handler) 243 | } 244 | 245 | // PostService_ServiceDesc is the grpc.ServiceDesc for PostService service. 246 | // It's only intended for direct use with grpc.RegisterService, 247 | // and not to be introspected or modified (even as a copy) 248 | var PostService_ServiceDesc = grpc.ServiceDesc{ 249 | ServiceName: "pb.PostService", 250 | HandlerType: (*PostServiceServer)(nil), 251 | Methods: []grpc.MethodDesc{ 252 | { 253 | MethodName: "CreatePost", 254 | Handler: _PostService_CreatePost_Handler, 255 | }, 256 | { 257 | MethodName: "GetPost", 258 | Handler: _PostService_GetPost_Handler, 259 | }, 260 | { 261 | MethodName: "UpdatePost", 262 | Handler: _PostService_UpdatePost_Handler, 263 | }, 264 | { 265 | MethodName: "DeletePost", 266 | Handler: _PostService_DeletePost_Handler, 267 | }, 268 | }, 269 | Streams: []grpc.StreamDesc{ 270 | { 271 | StreamName: "GetPosts", 272 | Handler: _PostService_GetPosts_Handler, 273 | ServerStreams: true, 274 | }, 275 | }, 276 | Metadata: "post_service.proto", 277 | } 278 | -------------------------------------------------------------------------------- /pb/rpc_create_post.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: rpc_create_post.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type CreatePostRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Title string `protobuf:"bytes,1,opt,name=Title,proto3" json:"Title,omitempty"` 29 | Content string `protobuf:"bytes,2,opt,name=Content,proto3" json:"Content,omitempty"` 30 | Image string `protobuf:"bytes,3,opt,name=Image,proto3" json:"Image,omitempty"` 31 | User string `protobuf:"bytes,4,opt,name=User,proto3" json:"User,omitempty"` 32 | } 33 | 34 | func (x *CreatePostRequest) Reset() { 35 | *x = CreatePostRequest{} 36 | if protoimpl.UnsafeEnabled { 37 | mi := &file_rpc_create_post_proto_msgTypes[0] 38 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 39 | ms.StoreMessageInfo(mi) 40 | } 41 | } 42 | 43 | func (x *CreatePostRequest) String() string { 44 | return protoimpl.X.MessageStringOf(x) 45 | } 46 | 47 | func (*CreatePostRequest) ProtoMessage() {} 48 | 49 | func (x *CreatePostRequest) ProtoReflect() protoreflect.Message { 50 | mi := &file_rpc_create_post_proto_msgTypes[0] 51 | if protoimpl.UnsafeEnabled && x != nil { 52 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 53 | if ms.LoadMessageInfo() == nil { 54 | ms.StoreMessageInfo(mi) 55 | } 56 | return ms 57 | } 58 | return mi.MessageOf(x) 59 | } 60 | 61 | // Deprecated: Use CreatePostRequest.ProtoReflect.Descriptor instead. 62 | func (*CreatePostRequest) Descriptor() ([]byte, []int) { 63 | return file_rpc_create_post_proto_rawDescGZIP(), []int{0} 64 | } 65 | 66 | func (x *CreatePostRequest) GetTitle() string { 67 | if x != nil { 68 | return x.Title 69 | } 70 | return "" 71 | } 72 | 73 | func (x *CreatePostRequest) GetContent() string { 74 | if x != nil { 75 | return x.Content 76 | } 77 | return "" 78 | } 79 | 80 | func (x *CreatePostRequest) GetImage() string { 81 | if x != nil { 82 | return x.Image 83 | } 84 | return "" 85 | } 86 | 87 | func (x *CreatePostRequest) GetUser() string { 88 | if x != nil { 89 | return x.User 90 | } 91 | return "" 92 | } 93 | 94 | var File_rpc_create_post_proto protoreflect.FileDescriptor 95 | 96 | var file_rpc_create_post_proto_rawDesc = []byte{ 97 | 0x0a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x73, 98 | 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x6d, 0x0a, 0x11, 0x43, 99 | 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 100 | 0x12, 0x14, 0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 101 | 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 102 | 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 103 | 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 104 | 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x04, 105 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 106 | 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 107 | 0x6f, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 108 | 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 109 | } 110 | 111 | var ( 112 | file_rpc_create_post_proto_rawDescOnce sync.Once 113 | file_rpc_create_post_proto_rawDescData = file_rpc_create_post_proto_rawDesc 114 | ) 115 | 116 | func file_rpc_create_post_proto_rawDescGZIP() []byte { 117 | file_rpc_create_post_proto_rawDescOnce.Do(func() { 118 | file_rpc_create_post_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_create_post_proto_rawDescData) 119 | }) 120 | return file_rpc_create_post_proto_rawDescData 121 | } 122 | 123 | var file_rpc_create_post_proto_msgTypes = make([]protoimpl.MessageInfo, 1) 124 | var file_rpc_create_post_proto_goTypes = []interface{}{ 125 | (*CreatePostRequest)(nil), // 0: pb.CreatePostRequest 126 | } 127 | var file_rpc_create_post_proto_depIdxs = []int32{ 128 | 0, // [0:0] is the sub-list for method output_type 129 | 0, // [0:0] is the sub-list for method input_type 130 | 0, // [0:0] is the sub-list for extension type_name 131 | 0, // [0:0] is the sub-list for extension extendee 132 | 0, // [0:0] is the sub-list for field type_name 133 | } 134 | 135 | func init() { file_rpc_create_post_proto_init() } 136 | func file_rpc_create_post_proto_init() { 137 | if File_rpc_create_post_proto != nil { 138 | return 139 | } 140 | if !protoimpl.UnsafeEnabled { 141 | file_rpc_create_post_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 142 | switch v := v.(*CreatePostRequest); i { 143 | case 0: 144 | return &v.state 145 | case 1: 146 | return &v.sizeCache 147 | case 2: 148 | return &v.unknownFields 149 | default: 150 | return nil 151 | } 152 | } 153 | } 154 | type x struct{} 155 | out := protoimpl.TypeBuilder{ 156 | File: protoimpl.DescBuilder{ 157 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 158 | RawDescriptor: file_rpc_create_post_proto_rawDesc, 159 | NumEnums: 0, 160 | NumMessages: 1, 161 | NumExtensions: 0, 162 | NumServices: 0, 163 | }, 164 | GoTypes: file_rpc_create_post_proto_goTypes, 165 | DependencyIndexes: file_rpc_create_post_proto_depIdxs, 166 | MessageInfos: file_rpc_create_post_proto_msgTypes, 167 | }.Build() 168 | File_rpc_create_post_proto = out.File 169 | file_rpc_create_post_proto_rawDesc = nil 170 | file_rpc_create_post_proto_goTypes = nil 171 | file_rpc_create_post_proto_depIdxs = nil 172 | } 173 | -------------------------------------------------------------------------------- /pb/rpc_signin_user.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: rpc_signin_user.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type SignInUserInput struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` 29 | Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` 30 | } 31 | 32 | func (x *SignInUserInput) Reset() { 33 | *x = SignInUserInput{} 34 | if protoimpl.UnsafeEnabled { 35 | mi := &file_rpc_signin_user_proto_msgTypes[0] 36 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 37 | ms.StoreMessageInfo(mi) 38 | } 39 | } 40 | 41 | func (x *SignInUserInput) String() string { 42 | return protoimpl.X.MessageStringOf(x) 43 | } 44 | 45 | func (*SignInUserInput) ProtoMessage() {} 46 | 47 | func (x *SignInUserInput) ProtoReflect() protoreflect.Message { 48 | mi := &file_rpc_signin_user_proto_msgTypes[0] 49 | if protoimpl.UnsafeEnabled && x != nil { 50 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 51 | if ms.LoadMessageInfo() == nil { 52 | ms.StoreMessageInfo(mi) 53 | } 54 | return ms 55 | } 56 | return mi.MessageOf(x) 57 | } 58 | 59 | // Deprecated: Use SignInUserInput.ProtoReflect.Descriptor instead. 60 | func (*SignInUserInput) Descriptor() ([]byte, []int) { 61 | return file_rpc_signin_user_proto_rawDescGZIP(), []int{0} 62 | } 63 | 64 | func (x *SignInUserInput) GetEmail() string { 65 | if x != nil { 66 | return x.Email 67 | } 68 | return "" 69 | } 70 | 71 | func (x *SignInUserInput) GetPassword() string { 72 | if x != nil { 73 | return x.Password 74 | } 75 | return "" 76 | } 77 | 78 | type SignInUserResponse struct { 79 | state protoimpl.MessageState 80 | sizeCache protoimpl.SizeCache 81 | unknownFields protoimpl.UnknownFields 82 | 83 | Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` 84 | AccessToken string `protobuf:"bytes,2,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` 85 | RefreshToken string `protobuf:"bytes,3,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"` 86 | } 87 | 88 | func (x *SignInUserResponse) Reset() { 89 | *x = SignInUserResponse{} 90 | if protoimpl.UnsafeEnabled { 91 | mi := &file_rpc_signin_user_proto_msgTypes[1] 92 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 93 | ms.StoreMessageInfo(mi) 94 | } 95 | } 96 | 97 | func (x *SignInUserResponse) String() string { 98 | return protoimpl.X.MessageStringOf(x) 99 | } 100 | 101 | func (*SignInUserResponse) ProtoMessage() {} 102 | 103 | func (x *SignInUserResponse) ProtoReflect() protoreflect.Message { 104 | mi := &file_rpc_signin_user_proto_msgTypes[1] 105 | if protoimpl.UnsafeEnabled && x != nil { 106 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 107 | if ms.LoadMessageInfo() == nil { 108 | ms.StoreMessageInfo(mi) 109 | } 110 | return ms 111 | } 112 | return mi.MessageOf(x) 113 | } 114 | 115 | // Deprecated: Use SignInUserResponse.ProtoReflect.Descriptor instead. 116 | func (*SignInUserResponse) Descriptor() ([]byte, []int) { 117 | return file_rpc_signin_user_proto_rawDescGZIP(), []int{1} 118 | } 119 | 120 | func (x *SignInUserResponse) GetStatus() string { 121 | if x != nil { 122 | return x.Status 123 | } 124 | return "" 125 | } 126 | 127 | func (x *SignInUserResponse) GetAccessToken() string { 128 | if x != nil { 129 | return x.AccessToken 130 | } 131 | return "" 132 | } 133 | 134 | func (x *SignInUserResponse) GetRefreshToken() string { 135 | if x != nil { 136 | return x.RefreshToken 137 | } 138 | return "" 139 | } 140 | 141 | var File_rpc_signin_user_proto protoreflect.FileDescriptor 142 | 143 | var file_rpc_signin_user_proto_rawDesc = []byte{ 144 | 0x0a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x5f, 0x75, 0x73, 0x65, 145 | 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x43, 0x0a, 0x0f, 0x53, 146 | 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x14, 147 | 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 148 | 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 149 | 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 150 | 0x22, 0x74, 0x0a, 0x12, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 151 | 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 152 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 153 | 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 154 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 155 | 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 156 | 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 157 | 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 158 | 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 0x67, 0x6f, 159 | 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 0x62, 0x62, 160 | 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 161 | } 162 | 163 | var ( 164 | file_rpc_signin_user_proto_rawDescOnce sync.Once 165 | file_rpc_signin_user_proto_rawDescData = file_rpc_signin_user_proto_rawDesc 166 | ) 167 | 168 | func file_rpc_signin_user_proto_rawDescGZIP() []byte { 169 | file_rpc_signin_user_proto_rawDescOnce.Do(func() { 170 | file_rpc_signin_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_signin_user_proto_rawDescData) 171 | }) 172 | return file_rpc_signin_user_proto_rawDescData 173 | } 174 | 175 | var file_rpc_signin_user_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 176 | var file_rpc_signin_user_proto_goTypes = []interface{}{ 177 | (*SignInUserInput)(nil), // 0: pb.SignInUserInput 178 | (*SignInUserResponse)(nil), // 1: pb.SignInUserResponse 179 | } 180 | var file_rpc_signin_user_proto_depIdxs = []int32{ 181 | 0, // [0:0] is the sub-list for method output_type 182 | 0, // [0:0] is the sub-list for method input_type 183 | 0, // [0:0] is the sub-list for extension type_name 184 | 0, // [0:0] is the sub-list for extension extendee 185 | 0, // [0:0] is the sub-list for field type_name 186 | } 187 | 188 | func init() { file_rpc_signin_user_proto_init() } 189 | func file_rpc_signin_user_proto_init() { 190 | if File_rpc_signin_user_proto != nil { 191 | return 192 | } 193 | if !protoimpl.UnsafeEnabled { 194 | file_rpc_signin_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 195 | switch v := v.(*SignInUserInput); i { 196 | case 0: 197 | return &v.state 198 | case 1: 199 | return &v.sizeCache 200 | case 2: 201 | return &v.unknownFields 202 | default: 203 | return nil 204 | } 205 | } 206 | file_rpc_signin_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 207 | switch v := v.(*SignInUserResponse); i { 208 | case 0: 209 | return &v.state 210 | case 1: 211 | return &v.sizeCache 212 | case 2: 213 | return &v.unknownFields 214 | default: 215 | return nil 216 | } 217 | } 218 | } 219 | type x struct{} 220 | out := protoimpl.TypeBuilder{ 221 | File: protoimpl.DescBuilder{ 222 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 223 | RawDescriptor: file_rpc_signin_user_proto_rawDesc, 224 | NumEnums: 0, 225 | NumMessages: 2, 226 | NumExtensions: 0, 227 | NumServices: 0, 228 | }, 229 | GoTypes: file_rpc_signin_user_proto_goTypes, 230 | DependencyIndexes: file_rpc_signin_user_proto_depIdxs, 231 | MessageInfos: file_rpc_signin_user_proto_msgTypes, 232 | }.Build() 233 | File_rpc_signin_user_proto = out.File 234 | file_rpc_signin_user_proto_rawDesc = nil 235 | file_rpc_signin_user_proto_goTypes = nil 236 | file_rpc_signin_user_proto_depIdxs = nil 237 | } 238 | -------------------------------------------------------------------------------- /pb/rpc_signup_user.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: rpc_signup_user.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type SignUpUserInput struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` 29 | Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` 30 | Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` 31 | PasswordConfirm string `protobuf:"bytes,4,opt,name=passwordConfirm,proto3" json:"passwordConfirm,omitempty"` 32 | } 33 | 34 | func (x *SignUpUserInput) Reset() { 35 | *x = SignUpUserInput{} 36 | if protoimpl.UnsafeEnabled { 37 | mi := &file_rpc_signup_user_proto_msgTypes[0] 38 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 39 | ms.StoreMessageInfo(mi) 40 | } 41 | } 42 | 43 | func (x *SignUpUserInput) String() string { 44 | return protoimpl.X.MessageStringOf(x) 45 | } 46 | 47 | func (*SignUpUserInput) ProtoMessage() {} 48 | 49 | func (x *SignUpUserInput) ProtoReflect() protoreflect.Message { 50 | mi := &file_rpc_signup_user_proto_msgTypes[0] 51 | if protoimpl.UnsafeEnabled && x != nil { 52 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 53 | if ms.LoadMessageInfo() == nil { 54 | ms.StoreMessageInfo(mi) 55 | } 56 | return ms 57 | } 58 | return mi.MessageOf(x) 59 | } 60 | 61 | // Deprecated: Use SignUpUserInput.ProtoReflect.Descriptor instead. 62 | func (*SignUpUserInput) Descriptor() ([]byte, []int) { 63 | return file_rpc_signup_user_proto_rawDescGZIP(), []int{0} 64 | } 65 | 66 | func (x *SignUpUserInput) GetName() string { 67 | if x != nil { 68 | return x.Name 69 | } 70 | return "" 71 | } 72 | 73 | func (x *SignUpUserInput) GetEmail() string { 74 | if x != nil { 75 | return x.Email 76 | } 77 | return "" 78 | } 79 | 80 | func (x *SignUpUserInput) GetPassword() string { 81 | if x != nil { 82 | return x.Password 83 | } 84 | return "" 85 | } 86 | 87 | func (x *SignUpUserInput) GetPasswordConfirm() string { 88 | if x != nil { 89 | return x.PasswordConfirm 90 | } 91 | return "" 92 | } 93 | 94 | type SignUpUserResponse struct { 95 | state protoimpl.MessageState 96 | sizeCache protoimpl.SizeCache 97 | unknownFields protoimpl.UnknownFields 98 | 99 | User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` 100 | } 101 | 102 | func (x *SignUpUserResponse) Reset() { 103 | *x = SignUpUserResponse{} 104 | if protoimpl.UnsafeEnabled { 105 | mi := &file_rpc_signup_user_proto_msgTypes[1] 106 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 107 | ms.StoreMessageInfo(mi) 108 | } 109 | } 110 | 111 | func (x *SignUpUserResponse) String() string { 112 | return protoimpl.X.MessageStringOf(x) 113 | } 114 | 115 | func (*SignUpUserResponse) ProtoMessage() {} 116 | 117 | func (x *SignUpUserResponse) ProtoReflect() protoreflect.Message { 118 | mi := &file_rpc_signup_user_proto_msgTypes[1] 119 | if protoimpl.UnsafeEnabled && x != nil { 120 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 121 | if ms.LoadMessageInfo() == nil { 122 | ms.StoreMessageInfo(mi) 123 | } 124 | return ms 125 | } 126 | return mi.MessageOf(x) 127 | } 128 | 129 | // Deprecated: Use SignUpUserResponse.ProtoReflect.Descriptor instead. 130 | func (*SignUpUserResponse) Descriptor() ([]byte, []int) { 131 | return file_rpc_signup_user_proto_rawDescGZIP(), []int{1} 132 | } 133 | 134 | func (x *SignUpUserResponse) GetUser() *User { 135 | if x != nil { 136 | return x.User 137 | } 138 | return nil 139 | } 140 | 141 | var File_rpc_signup_user_proto protoreflect.FileDescriptor 142 | 143 | var file_rpc_signup_user_proto_rawDesc = []byte{ 144 | 0x0a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x5f, 0x75, 0x73, 0x65, 145 | 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0a, 0x75, 0x73, 0x65, 146 | 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 147 | 0x55, 0x70, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 148 | 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 149 | 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 150 | 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 151 | 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 152 | 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x6e, 153 | 0x66, 0x69, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x61, 0x73, 0x73, 154 | 0x77, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x22, 0x32, 0x0a, 0x12, 0x53, 155 | 0x69, 0x67, 0x6e, 0x55, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 156 | 0x65, 0x12, 0x1c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 157 | 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x42, 158 | 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 159 | 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 160 | 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 161 | } 162 | 163 | var ( 164 | file_rpc_signup_user_proto_rawDescOnce sync.Once 165 | file_rpc_signup_user_proto_rawDescData = file_rpc_signup_user_proto_rawDesc 166 | ) 167 | 168 | func file_rpc_signup_user_proto_rawDescGZIP() []byte { 169 | file_rpc_signup_user_proto_rawDescOnce.Do(func() { 170 | file_rpc_signup_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_signup_user_proto_rawDescData) 171 | }) 172 | return file_rpc_signup_user_proto_rawDescData 173 | } 174 | 175 | var file_rpc_signup_user_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 176 | var file_rpc_signup_user_proto_goTypes = []interface{}{ 177 | (*SignUpUserInput)(nil), // 0: pb.SignUpUserInput 178 | (*SignUpUserResponse)(nil), // 1: pb.SignUpUserResponse 179 | (*User)(nil), // 2: pb.User 180 | } 181 | var file_rpc_signup_user_proto_depIdxs = []int32{ 182 | 2, // 0: pb.SignUpUserResponse.user:type_name -> pb.User 183 | 1, // [1:1] is the sub-list for method output_type 184 | 1, // [1:1] is the sub-list for method input_type 185 | 1, // [1:1] is the sub-list for extension type_name 186 | 1, // [1:1] is the sub-list for extension extendee 187 | 0, // [0:1] is the sub-list for field type_name 188 | } 189 | 190 | func init() { file_rpc_signup_user_proto_init() } 191 | func file_rpc_signup_user_proto_init() { 192 | if File_rpc_signup_user_proto != nil { 193 | return 194 | } 195 | file_user_proto_init() 196 | if !protoimpl.UnsafeEnabled { 197 | file_rpc_signup_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 198 | switch v := v.(*SignUpUserInput); i { 199 | case 0: 200 | return &v.state 201 | case 1: 202 | return &v.sizeCache 203 | case 2: 204 | return &v.unknownFields 205 | default: 206 | return nil 207 | } 208 | } 209 | file_rpc_signup_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 210 | switch v := v.(*SignUpUserResponse); i { 211 | case 0: 212 | return &v.state 213 | case 1: 214 | return &v.sizeCache 215 | case 2: 216 | return &v.unknownFields 217 | default: 218 | return nil 219 | } 220 | } 221 | } 222 | type x struct{} 223 | out := protoimpl.TypeBuilder{ 224 | File: protoimpl.DescBuilder{ 225 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 226 | RawDescriptor: file_rpc_signup_user_proto_rawDesc, 227 | NumEnums: 0, 228 | NumMessages: 2, 229 | NumExtensions: 0, 230 | NumServices: 0, 231 | }, 232 | GoTypes: file_rpc_signup_user_proto_goTypes, 233 | DependencyIndexes: file_rpc_signup_user_proto_depIdxs, 234 | MessageInfos: file_rpc_signup_user_proto_msgTypes, 235 | }.Build() 236 | File_rpc_signup_user_proto = out.File 237 | file_rpc_signup_user_proto_rawDesc = nil 238 | file_rpc_signup_user_proto_goTypes = nil 239 | file_rpc_signup_user_proto_depIdxs = nil 240 | } 241 | -------------------------------------------------------------------------------- /pb/rpc_update_post.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: rpc_update_post.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type UpdatePostRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` 29 | Title *string `protobuf:"bytes,2,opt,name=Title,proto3,oneof" json:"Title,omitempty"` 30 | Content *string `protobuf:"bytes,3,opt,name=Content,proto3,oneof" json:"Content,omitempty"` 31 | Image *string `protobuf:"bytes,4,opt,name=Image,proto3,oneof" json:"Image,omitempty"` 32 | User *string `protobuf:"bytes,5,opt,name=User,proto3,oneof" json:"User,omitempty"` 33 | } 34 | 35 | func (x *UpdatePostRequest) Reset() { 36 | *x = UpdatePostRequest{} 37 | if protoimpl.UnsafeEnabled { 38 | mi := &file_rpc_update_post_proto_msgTypes[0] 39 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 40 | ms.StoreMessageInfo(mi) 41 | } 42 | } 43 | 44 | func (x *UpdatePostRequest) String() string { 45 | return protoimpl.X.MessageStringOf(x) 46 | } 47 | 48 | func (*UpdatePostRequest) ProtoMessage() {} 49 | 50 | func (x *UpdatePostRequest) ProtoReflect() protoreflect.Message { 51 | mi := &file_rpc_update_post_proto_msgTypes[0] 52 | if protoimpl.UnsafeEnabled && x != nil { 53 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 54 | if ms.LoadMessageInfo() == nil { 55 | ms.StoreMessageInfo(mi) 56 | } 57 | return ms 58 | } 59 | return mi.MessageOf(x) 60 | } 61 | 62 | // Deprecated: Use UpdatePostRequest.ProtoReflect.Descriptor instead. 63 | func (*UpdatePostRequest) Descriptor() ([]byte, []int) { 64 | return file_rpc_update_post_proto_rawDescGZIP(), []int{0} 65 | } 66 | 67 | func (x *UpdatePostRequest) GetId() string { 68 | if x != nil { 69 | return x.Id 70 | } 71 | return "" 72 | } 73 | 74 | func (x *UpdatePostRequest) GetTitle() string { 75 | if x != nil && x.Title != nil { 76 | return *x.Title 77 | } 78 | return "" 79 | } 80 | 81 | func (x *UpdatePostRequest) GetContent() string { 82 | if x != nil && x.Content != nil { 83 | return *x.Content 84 | } 85 | return "" 86 | } 87 | 88 | func (x *UpdatePostRequest) GetImage() string { 89 | if x != nil && x.Image != nil { 90 | return *x.Image 91 | } 92 | return "" 93 | } 94 | 95 | func (x *UpdatePostRequest) GetUser() string { 96 | if x != nil && x.User != nil { 97 | return *x.User 98 | } 99 | return "" 100 | } 101 | 102 | var File_rpc_update_post_proto protoreflect.FileDescriptor 103 | 104 | var file_rpc_update_post_proto_rawDesc = []byte{ 105 | 0x0a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x73, 106 | 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xba, 0x01, 0x0a, 0x11, 107 | 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 108 | 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 109 | 0x64, 0x12, 0x19, 0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 110 | 0x48, 0x00, 0x52, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 111 | 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 112 | 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x49, 113 | 0x6d, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x05, 0x49, 0x6d, 114 | 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x05, 115 | 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 116 | 0x08, 0x0a, 0x06, 0x5f, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x43, 0x6f, 117 | 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x42, 118 | 0x07, 0x0a, 0x05, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 119 | 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 120 | 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 121 | 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 122 | } 123 | 124 | var ( 125 | file_rpc_update_post_proto_rawDescOnce sync.Once 126 | file_rpc_update_post_proto_rawDescData = file_rpc_update_post_proto_rawDesc 127 | ) 128 | 129 | func file_rpc_update_post_proto_rawDescGZIP() []byte { 130 | file_rpc_update_post_proto_rawDescOnce.Do(func() { 131 | file_rpc_update_post_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_update_post_proto_rawDescData) 132 | }) 133 | return file_rpc_update_post_proto_rawDescData 134 | } 135 | 136 | var file_rpc_update_post_proto_msgTypes = make([]protoimpl.MessageInfo, 1) 137 | var file_rpc_update_post_proto_goTypes = []interface{}{ 138 | (*UpdatePostRequest)(nil), // 0: pb.UpdatePostRequest 139 | } 140 | var file_rpc_update_post_proto_depIdxs = []int32{ 141 | 0, // [0:0] is the sub-list for method output_type 142 | 0, // [0:0] is the sub-list for method input_type 143 | 0, // [0:0] is the sub-list for extension type_name 144 | 0, // [0:0] is the sub-list for extension extendee 145 | 0, // [0:0] is the sub-list for field type_name 146 | } 147 | 148 | func init() { file_rpc_update_post_proto_init() } 149 | func file_rpc_update_post_proto_init() { 150 | if File_rpc_update_post_proto != nil { 151 | return 152 | } 153 | if !protoimpl.UnsafeEnabled { 154 | file_rpc_update_post_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 155 | switch v := v.(*UpdatePostRequest); i { 156 | case 0: 157 | return &v.state 158 | case 1: 159 | return &v.sizeCache 160 | case 2: 161 | return &v.unknownFields 162 | default: 163 | return nil 164 | } 165 | } 166 | } 167 | file_rpc_update_post_proto_msgTypes[0].OneofWrappers = []interface{}{} 168 | type x struct{} 169 | out := protoimpl.TypeBuilder{ 170 | File: protoimpl.DescBuilder{ 171 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 172 | RawDescriptor: file_rpc_update_post_proto_rawDesc, 173 | NumEnums: 0, 174 | NumMessages: 1, 175 | NumExtensions: 0, 176 | NumServices: 0, 177 | }, 178 | GoTypes: file_rpc_update_post_proto_goTypes, 179 | DependencyIndexes: file_rpc_update_post_proto_depIdxs, 180 | MessageInfos: file_rpc_update_post_proto_msgTypes, 181 | }.Build() 182 | File_rpc_update_post_proto = out.File 183 | file_rpc_update_post_proto_rawDesc = nil 184 | file_rpc_update_post_proto_goTypes = nil 185 | file_rpc_update_post_proto_depIdxs = nil 186 | } 187 | -------------------------------------------------------------------------------- /pb/user.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: user.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | timestamppb "google.golang.org/protobuf/types/known/timestamppb" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type User struct { 25 | state protoimpl.MessageState 26 | sizeCache protoimpl.SizeCache 27 | unknownFields protoimpl.UnknownFields 28 | 29 | Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` 30 | Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` 31 | Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` 32 | Role string `protobuf:"bytes,4,opt,name=role,proto3" json:"role,omitempty"` 33 | CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` 34 | UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` 35 | } 36 | 37 | func (x *User) Reset() { 38 | *x = User{} 39 | if protoimpl.UnsafeEnabled { 40 | mi := &file_user_proto_msgTypes[0] 41 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 42 | ms.StoreMessageInfo(mi) 43 | } 44 | } 45 | 46 | func (x *User) String() string { 47 | return protoimpl.X.MessageStringOf(x) 48 | } 49 | 50 | func (*User) ProtoMessage() {} 51 | 52 | func (x *User) ProtoReflect() protoreflect.Message { 53 | mi := &file_user_proto_msgTypes[0] 54 | if protoimpl.UnsafeEnabled && x != nil { 55 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 56 | if ms.LoadMessageInfo() == nil { 57 | ms.StoreMessageInfo(mi) 58 | } 59 | return ms 60 | } 61 | return mi.MessageOf(x) 62 | } 63 | 64 | // Deprecated: Use User.ProtoReflect.Descriptor instead. 65 | func (*User) Descriptor() ([]byte, []int) { 66 | return file_user_proto_rawDescGZIP(), []int{0} 67 | } 68 | 69 | func (x *User) GetId() string { 70 | if x != nil { 71 | return x.Id 72 | } 73 | return "" 74 | } 75 | 76 | func (x *User) GetName() string { 77 | if x != nil { 78 | return x.Name 79 | } 80 | return "" 81 | } 82 | 83 | func (x *User) GetEmail() string { 84 | if x != nil { 85 | return x.Email 86 | } 87 | return "" 88 | } 89 | 90 | func (x *User) GetRole() string { 91 | if x != nil { 92 | return x.Role 93 | } 94 | return "" 95 | } 96 | 97 | func (x *User) GetCreatedAt() *timestamppb.Timestamp { 98 | if x != nil { 99 | return x.CreatedAt 100 | } 101 | return nil 102 | } 103 | 104 | func (x *User) GetUpdatedAt() *timestamppb.Timestamp { 105 | if x != nil { 106 | return x.UpdatedAt 107 | } 108 | return nil 109 | } 110 | 111 | type UserResponse struct { 112 | state protoimpl.MessageState 113 | sizeCache protoimpl.SizeCache 114 | unknownFields protoimpl.UnknownFields 115 | 116 | User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` 117 | } 118 | 119 | func (x *UserResponse) Reset() { 120 | *x = UserResponse{} 121 | if protoimpl.UnsafeEnabled { 122 | mi := &file_user_proto_msgTypes[1] 123 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 124 | ms.StoreMessageInfo(mi) 125 | } 126 | } 127 | 128 | func (x *UserResponse) String() string { 129 | return protoimpl.X.MessageStringOf(x) 130 | } 131 | 132 | func (*UserResponse) ProtoMessage() {} 133 | 134 | func (x *UserResponse) ProtoReflect() protoreflect.Message { 135 | mi := &file_user_proto_msgTypes[1] 136 | if protoimpl.UnsafeEnabled && x != nil { 137 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 138 | if ms.LoadMessageInfo() == nil { 139 | ms.StoreMessageInfo(mi) 140 | } 141 | return ms 142 | } 143 | return mi.MessageOf(x) 144 | } 145 | 146 | // Deprecated: Use UserResponse.ProtoReflect.Descriptor instead. 147 | func (*UserResponse) Descriptor() ([]byte, []int) { 148 | return file_user_proto_rawDescGZIP(), []int{1} 149 | } 150 | 151 | func (x *UserResponse) GetUser() *User { 152 | if x != nil { 153 | return x.User 154 | } 155 | return nil 156 | } 157 | 158 | type GenericResponse struct { 159 | state protoimpl.MessageState 160 | sizeCache protoimpl.SizeCache 161 | unknownFields protoimpl.UnknownFields 162 | 163 | Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` 164 | Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` 165 | } 166 | 167 | func (x *GenericResponse) Reset() { 168 | *x = GenericResponse{} 169 | if protoimpl.UnsafeEnabled { 170 | mi := &file_user_proto_msgTypes[2] 171 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 172 | ms.StoreMessageInfo(mi) 173 | } 174 | } 175 | 176 | func (x *GenericResponse) String() string { 177 | return protoimpl.X.MessageStringOf(x) 178 | } 179 | 180 | func (*GenericResponse) ProtoMessage() {} 181 | 182 | func (x *GenericResponse) ProtoReflect() protoreflect.Message { 183 | mi := &file_user_proto_msgTypes[2] 184 | if protoimpl.UnsafeEnabled && x != nil { 185 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 186 | if ms.LoadMessageInfo() == nil { 187 | ms.StoreMessageInfo(mi) 188 | } 189 | return ms 190 | } 191 | return mi.MessageOf(x) 192 | } 193 | 194 | // Deprecated: Use GenericResponse.ProtoReflect.Descriptor instead. 195 | func (*GenericResponse) Descriptor() ([]byte, []int) { 196 | return file_user_proto_rawDescGZIP(), []int{2} 197 | } 198 | 199 | func (x *GenericResponse) GetStatus() string { 200 | if x != nil { 201 | return x.Status 202 | } 203 | return "" 204 | } 205 | 206 | func (x *GenericResponse) GetMessage() string { 207 | if x != nil { 208 | return x.Message 209 | } 210 | return "" 211 | } 212 | 213 | var File_user_proto protoreflect.FileDescriptor 214 | 215 | var file_user_proto_rawDesc = []byte{ 216 | 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 217 | 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 218 | 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 219 | 0x6f, 0x22, 0xca, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 220 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 221 | 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 222 | 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 223 | 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 224 | 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 225 | 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 226 | 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 227 | 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 228 | 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 229 | 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 230 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 231 | 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x2c, 232 | 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 233 | 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 234 | 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x43, 0x0a, 0x0f, 235 | 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 236 | 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 237 | 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 238 | 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 239 | 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 240 | 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 241 | 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 242 | 0x6f, 0x33, 243 | } 244 | 245 | var ( 246 | file_user_proto_rawDescOnce sync.Once 247 | file_user_proto_rawDescData = file_user_proto_rawDesc 248 | ) 249 | 250 | func file_user_proto_rawDescGZIP() []byte { 251 | file_user_proto_rawDescOnce.Do(func() { 252 | file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData) 253 | }) 254 | return file_user_proto_rawDescData 255 | } 256 | 257 | var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 258 | var file_user_proto_goTypes = []interface{}{ 259 | (*User)(nil), // 0: pb.User 260 | (*UserResponse)(nil), // 1: pb.UserResponse 261 | (*GenericResponse)(nil), // 2: pb.GenericResponse 262 | (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp 263 | } 264 | var file_user_proto_depIdxs = []int32{ 265 | 3, // 0: pb.User.created_at:type_name -> google.protobuf.Timestamp 266 | 3, // 1: pb.User.updated_at:type_name -> google.protobuf.Timestamp 267 | 0, // 2: pb.UserResponse.user:type_name -> pb.User 268 | 3, // [3:3] is the sub-list for method output_type 269 | 3, // [3:3] is the sub-list for method input_type 270 | 3, // [3:3] is the sub-list for extension type_name 271 | 3, // [3:3] is the sub-list for extension extendee 272 | 0, // [0:3] is the sub-list for field type_name 273 | } 274 | 275 | func init() { file_user_proto_init() } 276 | func file_user_proto_init() { 277 | if File_user_proto != nil { 278 | return 279 | } 280 | if !protoimpl.UnsafeEnabled { 281 | file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 282 | switch v := v.(*User); i { 283 | case 0: 284 | return &v.state 285 | case 1: 286 | return &v.sizeCache 287 | case 2: 288 | return &v.unknownFields 289 | default: 290 | return nil 291 | } 292 | } 293 | file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 294 | switch v := v.(*UserResponse); i { 295 | case 0: 296 | return &v.state 297 | case 1: 298 | return &v.sizeCache 299 | case 2: 300 | return &v.unknownFields 301 | default: 302 | return nil 303 | } 304 | } 305 | file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 306 | switch v := v.(*GenericResponse); i { 307 | case 0: 308 | return &v.state 309 | case 1: 310 | return &v.sizeCache 311 | case 2: 312 | return &v.unknownFields 313 | default: 314 | return nil 315 | } 316 | } 317 | } 318 | type x struct{} 319 | out := protoimpl.TypeBuilder{ 320 | File: protoimpl.DescBuilder{ 321 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 322 | RawDescriptor: file_user_proto_rawDesc, 323 | NumEnums: 0, 324 | NumMessages: 3, 325 | NumExtensions: 0, 326 | NumServices: 0, 327 | }, 328 | GoTypes: file_user_proto_goTypes, 329 | DependencyIndexes: file_user_proto_depIdxs, 330 | MessageInfos: file_user_proto_msgTypes, 331 | }.Build() 332 | File_user_proto = out.File 333 | file_user_proto_rawDesc = nil 334 | file_user_proto_goTypes = nil 335 | file_user_proto_depIdxs = nil 336 | } 337 | -------------------------------------------------------------------------------- /pb/user_service.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.20.1 5 | // source: user_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type GetMeRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` 29 | } 30 | 31 | func (x *GetMeRequest) Reset() { 32 | *x = GetMeRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_user_service_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *GetMeRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*GetMeRequest) ProtoMessage() {} 45 | 46 | func (x *GetMeRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_user_service_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use GetMeRequest.ProtoReflect.Descriptor instead. 59 | func (*GetMeRequest) Descriptor() ([]byte, []int) { 60 | return file_user_service_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *GetMeRequest) GetId() string { 64 | if x != nil { 65 | return x.Id 66 | } 67 | return "" 68 | } 69 | 70 | var File_user_service_proto protoreflect.FileDescriptor 71 | 72 | var file_user_service_proto_rawDesc = []byte{ 73 | 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 74 | 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 75 | 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1e, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x52, 0x65, 0x71, 76 | 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 77 | 0x52, 0x02, 0x49, 0x64, 0x32, 0x3c, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 78 | 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x12, 0x10, 0x2e, 0x70, 79 | 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 80 | 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 81 | 0x22, 0x00, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 82 | 0x2f, 0x77, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x76, 0x6f, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 83 | 0x2d, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 84 | 0x74, 0x6f, 0x33, 85 | } 86 | 87 | var ( 88 | file_user_service_proto_rawDescOnce sync.Once 89 | file_user_service_proto_rawDescData = file_user_service_proto_rawDesc 90 | ) 91 | 92 | func file_user_service_proto_rawDescGZIP() []byte { 93 | file_user_service_proto_rawDescOnce.Do(func() { 94 | file_user_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_service_proto_rawDescData) 95 | }) 96 | return file_user_service_proto_rawDescData 97 | } 98 | 99 | var file_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) 100 | var file_user_service_proto_goTypes = []interface{}{ 101 | (*GetMeRequest)(nil), // 0: pb.GetMeRequest 102 | (*UserResponse)(nil), // 1: pb.UserResponse 103 | } 104 | var file_user_service_proto_depIdxs = []int32{ 105 | 0, // 0: pb.UserService.GetMe:input_type -> pb.GetMeRequest 106 | 1, // 1: pb.UserService.GetMe:output_type -> pb.UserResponse 107 | 1, // [1:2] is the sub-list for method output_type 108 | 0, // [0:1] is the sub-list for method input_type 109 | 0, // [0:0] is the sub-list for extension type_name 110 | 0, // [0:0] is the sub-list for extension extendee 111 | 0, // [0:0] is the sub-list for field type_name 112 | } 113 | 114 | func init() { file_user_service_proto_init() } 115 | func file_user_service_proto_init() { 116 | if File_user_service_proto != nil { 117 | return 118 | } 119 | file_user_proto_init() 120 | if !protoimpl.UnsafeEnabled { 121 | file_user_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 122 | switch v := v.(*GetMeRequest); i { 123 | case 0: 124 | return &v.state 125 | case 1: 126 | return &v.sizeCache 127 | case 2: 128 | return &v.unknownFields 129 | default: 130 | return nil 131 | } 132 | } 133 | } 134 | type x struct{} 135 | out := protoimpl.TypeBuilder{ 136 | File: protoimpl.DescBuilder{ 137 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 138 | RawDescriptor: file_user_service_proto_rawDesc, 139 | NumEnums: 0, 140 | NumMessages: 1, 141 | NumExtensions: 0, 142 | NumServices: 1, 143 | }, 144 | GoTypes: file_user_service_proto_goTypes, 145 | DependencyIndexes: file_user_service_proto_depIdxs, 146 | MessageInfos: file_user_service_proto_msgTypes, 147 | }.Build() 148 | File_user_service_proto = out.File 149 | file_user_service_proto_rawDesc = nil 150 | file_user_service_proto_goTypes = nil 151 | file_user_service_proto_depIdxs = nil 152 | } 153 | -------------------------------------------------------------------------------- /pb/user_service_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.2.0 4 | // - protoc v3.20.1 5 | // source: user_service.proto 6 | 7 | package pb 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.32.0 or later. 19 | const _ = grpc.SupportPackageIsVersion7 20 | 21 | // UserServiceClient is the client API for UserService service. 22 | // 23 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 24 | type UserServiceClient interface { 25 | GetMe(ctx context.Context, in *GetMeRequest, opts ...grpc.CallOption) (*UserResponse, error) 26 | } 27 | 28 | type userServiceClient struct { 29 | cc grpc.ClientConnInterface 30 | } 31 | 32 | func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { 33 | return &userServiceClient{cc} 34 | } 35 | 36 | func (c *userServiceClient) GetMe(ctx context.Context, in *GetMeRequest, opts ...grpc.CallOption) (*UserResponse, error) { 37 | out := new(UserResponse) 38 | err := c.cc.Invoke(ctx, "/pb.UserService/GetMe", in, out, opts...) 39 | if err != nil { 40 | return nil, err 41 | } 42 | return out, nil 43 | } 44 | 45 | // UserServiceServer is the server API for UserService service. 46 | // All implementations must embed UnimplementedUserServiceServer 47 | // for forward compatibility 48 | type UserServiceServer interface { 49 | GetMe(context.Context, *GetMeRequest) (*UserResponse, error) 50 | mustEmbedUnimplementedUserServiceServer() 51 | } 52 | 53 | // UnimplementedUserServiceServer must be embedded to have forward compatible implementations. 54 | type UnimplementedUserServiceServer struct { 55 | } 56 | 57 | func (UnimplementedUserServiceServer) GetMe(context.Context, *GetMeRequest) (*UserResponse, error) { 58 | return nil, status.Errorf(codes.Unimplemented, "method GetMe not implemented") 59 | } 60 | func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} 61 | 62 | // UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. 63 | // Use of this interface is not recommended, as added methods to UserServiceServer will 64 | // result in compilation errors. 65 | type UnsafeUserServiceServer interface { 66 | mustEmbedUnimplementedUserServiceServer() 67 | } 68 | 69 | func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { 70 | s.RegisterService(&UserService_ServiceDesc, srv) 71 | } 72 | 73 | func _UserService_GetMe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 74 | in := new(GetMeRequest) 75 | if err := dec(in); err != nil { 76 | return nil, err 77 | } 78 | if interceptor == nil { 79 | return srv.(UserServiceServer).GetMe(ctx, in) 80 | } 81 | info := &grpc.UnaryServerInfo{ 82 | Server: srv, 83 | FullMethod: "/pb.UserService/GetMe", 84 | } 85 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 86 | return srv.(UserServiceServer).GetMe(ctx, req.(*GetMeRequest)) 87 | } 88 | return interceptor(ctx, in, info, handler) 89 | } 90 | 91 | // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. 92 | // It's only intended for direct use with grpc.RegisterService, 93 | // and not to be introspected or modified (even as a copy) 94 | var UserService_ServiceDesc = grpc.ServiceDesc{ 95 | ServiceName: "pb.UserService", 96 | HandlerType: (*UserServiceServer)(nil), 97 | Methods: []grpc.MethodDesc{ 98 | { 99 | MethodName: "GetMe", 100 | Handler: _UserService_GetMe_Handler, 101 | }, 102 | }, 103 | Streams: []grpc.StreamDesc{}, 104 | Metadata: "user_service.proto", 105 | } 106 | -------------------------------------------------------------------------------- /proto-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf pb/*.go 4 | protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \ 5 | --go-grpc_out=pb --go-grpc_opt=paths=source_relative \ 6 | proto/*.proto -------------------------------------------------------------------------------- /proto/auth_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | import "rpc_signin_user.proto"; 6 | import "rpc_signup_user.proto"; 7 | import "user.proto"; 8 | 9 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 10 | 11 | service AuthService { 12 | rpc SignUpUser(SignUpUserInput) returns (GenericResponse) {} 13 | rpc SignInUser(SignInUserInput) returns (SignInUserResponse) {} 14 | rpc VerifyEmail(VerifyEmailRequest) returns (GenericResponse) {} 15 | } 16 | 17 | message VerifyEmailRequest { string verificationCode = 1; } -------------------------------------------------------------------------------- /proto/post.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | import "google/protobuf/timestamp.proto"; 7 | 8 | message Post { 9 | string Id = 1; 10 | string Title = 2; 11 | string Content = 3; 12 | string Image = 4; 13 | string User = 5; 14 | google.protobuf.Timestamp created_at = 6; 15 | google.protobuf.Timestamp updated_at = 7; 16 | } 17 | 18 | message PostResponse { Post post = 1; } 19 | -------------------------------------------------------------------------------- /proto/post_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | import "post.proto"; 7 | import "rpc_create_post.proto"; 8 | import "rpc_update_post.proto"; 9 | 10 | service PostService { 11 | rpc CreatePost(CreatePostRequest) returns (PostResponse) {} 12 | rpc GetPost(PostRequest) returns (PostResponse) {} 13 | rpc GetPosts(GetPostsRequest) returns (stream Post) {} 14 | rpc UpdatePost(UpdatePostRequest) returns (PostResponse) {} 15 | rpc DeletePost(PostRequest) returns (DeletePostResponse) {} 16 | } 17 | 18 | message GetPostsRequest { 19 | optional int64 page = 1; 20 | optional int64 limit = 2; 21 | } 22 | 23 | message PostRequest { string Id = 1; } 24 | 25 | message DeletePostResponse { bool success = 1; } -------------------------------------------------------------------------------- /proto/rpc_create_post.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | 7 | message CreatePostRequest { 8 | string Title = 1; 9 | string Content = 2; 10 | string Image = 3; 11 | string User = 4; 12 | } 13 | -------------------------------------------------------------------------------- /proto/rpc_signin_user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | 7 | message SignInUserInput { 8 | string email = 1; 9 | string password = 2; 10 | } 11 | 12 | message SignInUserResponse { 13 | string status = 1; 14 | string access_token = 2; 15 | string refresh_token = 3; 16 | } -------------------------------------------------------------------------------- /proto/rpc_signup_user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | 7 | import "user.proto"; 8 | 9 | message SignUpUserInput { 10 | string name = 1; 11 | string email = 2; 12 | string password = 3; 13 | string passwordConfirm = 4; 14 | } 15 | 16 | message SignUpUserResponse { User user = 1; } 17 | -------------------------------------------------------------------------------- /proto/rpc_update_post.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 6 | 7 | message UpdatePostRequest { 8 | string Id = 1; 9 | optional string Title = 2; 10 | optional string Content = 3; 11 | optional string Image = 4; 12 | optional string User = 5; 13 | } 14 | -------------------------------------------------------------------------------- /proto/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | import "google/protobuf/timestamp.proto"; 6 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 7 | 8 | message User { 9 | string id = 1; 10 | string name = 2; 11 | string email = 3; 12 | string role = 4; 13 | google.protobuf.Timestamp created_at = 5; 14 | google.protobuf.Timestamp updated_at = 6; 15 | } 16 | 17 | message UserResponse { User user = 1; } 18 | 19 | message GenericResponse { 20 | string status = 1; 21 | string message = 2; 22 | } -------------------------------------------------------------------------------- /proto/user_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | import "user.proto"; 6 | 7 | option go_package = "github.com/wpcodevo/golang-mongodb/pb"; 8 | 9 | service UserService { 10 | rpc GetMe(GetMeRequest) returns (UserResponse) {} 11 | } 12 | 13 | message GetMeRequest { string Id = 1; } 14 | -------------------------------------------------------------------------------- /readMe.md: -------------------------------------------------------------------------------- 1 | # Build gRPC Server API & Client with Golang and MongoDB 2 | 3 | ## 1. API with Golang + MongoDB + Redis + Gin Gonic: Project Setup 4 | 5 | In this article, you'll learn how to set up a Golang application with MongoDB-Go-driver, Gin Gonic, and Go Redis. Later, we'll access both the Redis and MongoDB databases directly in VS Code using a MySQL VS Code extension. 6 | 7 | ![API with Golang + MongoDB + Redis + Gin Gonic: Project Setup](https://codevoweb.com/wp-content/uploads/2022/05/API-with-Golang-MongoDB-Redis-and-Gin-Gonic-Project-Setup.webp) 8 | 9 | ### Topics Covered 10 | 11 | - Setup Golang with MongoDB and Redis 12 | - Creating MongoDB and Redis Database with Docker-compose 13 | - Setup Environment Variables 14 | - How to Connect Golang App to Redis and MongoDB 15 | - Test the Golang API 16 | - How to Connect to MongoDB and Redis Servers in VS Code 17 | 18 | Read the entire article here: [https://codevoweb.com/api-golang-mongodb-gin-gonic-project-setup](https://codevoweb.com/api-golang-mongodb-gin-gonic-project-setup) 19 | 20 | 21 | ## 2. Golang & MongoDB: JWT Authentication and Authorization 22 | 23 | In this article, you'll learn how to implement RS256 JWT (JSON Web Token) Authentication and Authorization with Golang, Gin Gonic, MongoDB-Go-driver, and Docker-compose. 24 | 25 | ![Golang & MongoDB: JWT Authentication and Authorization](https://codevoweb.com/wp-content/uploads/2022/05/Golang-and-MongoDB-JWT-Authentication-and-Authorization.webp) 26 | 27 | ### Topics Covered 28 | 29 | - Golang & MongoDB JWT Authentication Overview 30 | - JWT Authentication Example with Golang and MongoDB 31 | - How to Generate Public and Private Keys 32 | - Update Environment Variables with Viper 33 | - Creating the User models with structs 34 | - Creating an Auth and User Interfaces 35 | - Authentication Interface 36 | - User Interface 37 | - Create utility functions to hash and verify password 38 | - Create services that interact with the database 39 | - Auth interface implementation 40 | - User interface implementation 41 | - Create a utility function to sign and verify JWT tokens 42 | - Create Json Web Token 43 | - Verify JSON Web Token 44 | - Create the authentication controllers 45 | - Signup user controller 46 | - Login user controller 47 | - Refresh access token controller 48 | - Logout user controller 49 | - Authentication Middleware Guard 50 | - Create the user controllers 51 | - Create API Routes with Gin 52 | - Auth Routes 53 | - User Routes 54 | - Add the Routes to the Gin Middleware Pipeline 55 | 56 | Read the entire article here: [https://codevoweb.com/golang-mongodb-jwt-authentication-authorization](https://codevoweb.com/golang-mongodb-jwt-authentication-authorization) 57 | 58 | ## 3. API with Golang + MongoDB: Send HTML Emails with Gomail 59 | 60 | In this article, you'll learn how to send HTML emails with Golang, Gomail, MongoDB-Go-Driver, Redis, and Docker-compose. Also, you'll learn how to generate HTML templates with the standard Golang html/template package. 61 | 62 | ![API with Golang + MongoDB: Send HTML Emails with Gomail](https://codevoweb.com/wp-content/uploads/2022/05/API-with-Golang-MongoDB-Send-HTML-Emails-with-Gomail.webp) 63 | 64 | ### Topics Covered 65 | 66 | - Send Emails with Golang, MongoDB, and Gomail Overview 67 | - Creating the HTML Email Templates with Golang 68 | - Create an SMTP Provider Account 69 | - Load and Validate Environment Variables Viper 70 | - Create a Utility Function to Send the Emails 71 | - Update the SignUp Controller 72 | 73 | Read the entire article here: [https://codevoweb.com/api-golang-mongodb-send-html-emails-gomail](https://codevoweb.com/api-golang-mongodb-send-html-emails-gomail) 74 | 75 | 76 | ## 4. API with Golang, Gin Gonic & MongoDB: Forget/Reset Password 77 | 78 | In this article, you'll learn how to implement forget/reset password functionality with Golang, Gin Gonic, Gomail, MongoDB-Go-driver, Redis, and Docker-compose. 79 | 80 | ![API with Golang, Gin Gonic & MongoDB: Forget/Reset Password](https://codevoweb.com/wp-content/uploads/2022/05/API-with-Golang-Gin-Gonic-MongoDB-Forget-Reset-Password.webp) 81 | 82 | ### Topics Covered 83 | 84 | - Forget/Reset Password with Golang, Gin, and MongoDB 85 | - Create the MongoDB Model Structs 86 | - Create the HTML Email Templates with Golang 87 | - Define a Utility Function to Parse the HTML Templates 88 | - Create a Function to Send the HTML Emails 89 | - Add the Forgot Password Controller 90 | - Add the Reset Password Controller 91 | - Register the Gin API Routes 92 | 93 | Read the entire article here: [https://codevoweb.com/api-golang-gin-gonic-mongodb-forget-reset-password](https://codevoweb.com/api-golang-gin-gonic-mongodb-forget-reset-password) 94 | 95 | 96 | ## 5. Build Golang gRPC Server and Client: SignUp User & Verify Email 97 | 98 | In this article, you'll learn how to create a gRPC server to register a user and verify their email address using Golang, MongoDB-Go-driver, Gomail, and Docker-compose. 99 | 100 | ![Build Golang gRPC Server and Client: SignUp User & Verify Email](https://codevoweb.com/wp-content/uploads/2022/05/Build-Golang-gRPC-Server-and-Client-SignUp-User-Verify-Email.webp) 101 | 102 | ### Topics Covered 103 | 104 | - gRPC Project setup in Golang 105 | - Create the gRPC Request and Response Messages 106 | - Define the gRPC User messages 107 | - Define the gRPC Request and Response Message to SignUp User 108 | - Create the gRPC Service Methods 109 | - Generate the gRPC client and server interfaces 110 | - Start the gRPC Server 111 | - Test the gRPC API Server with Golang Evans 112 | - Create the gRPC API Controllers 113 | - Register User gRPC Controller 114 | - Verify User gRPC Controller 115 | - Create the gRPC Client to Register a User 116 | 117 | Read the entire article here: [https://codevoweb.com/golang-grpc-server-and-client-signup-user-verify-email](https://codevoweb.com/golang-grpc-server-and-client-signup-user-verify-email) 118 | 119 | ## 6. Build Golang gRPC Server and Client: Access & Refresh Tokens 120 | 121 | In this article, you'll learn how to implement JWT access and refresh tokens with gRPC using Golang, MongoDB-Go-driver, Gomail, Docker, and Docker-compose. 122 | 123 | ![Build Golang gRPC Server and Client: Access & Refresh Tokens](https://codevoweb.com/wp-content/uploads/2022/05/Build-Golang-gRPC-Server-and-Client-Access-Refresh-Tokens.webp) 124 | 125 | ### Topics Covered 126 | 127 | - Create the gRPC Request and Response Messages 128 | - Create the gRPC User messages 129 | - Define the gRPC Request and Response Message to Login User 130 | - Update the Authentication gRPC Service 131 | - Create a gRPC User Service 132 | - Create the gRPC Controllers 133 | - Create the gRPC Servers 134 | - Register the gRPC Servers 135 | - Create the gRPC Clients in Golang 136 | - Connect the gRPC Client to the gRPC Server 137 | 138 | Read the entire article here: [https://codevoweb.com/golang-grpc-server-and-client-access-refresh-tokens](https://codevoweb.com/golang-grpc-server-and-client-access-refresh-tokens) 139 | 140 | ## 7. Build CRUD RESTful API Server with Golang, Gin, and MongoDB 141 | 142 | In this article, you'll learn how to build a CRUD RESTful API server with Golang, Gin Gonic, MongoDB-Go-driver, Docker, and Docker-compose. 143 | 144 | ![Build CRUD RESTful API Server with Golang, Gin, and MongoDB](https://codevoweb.com/wp-content/uploads/2022/05/Build-CRUD-RESTful-API-Server-with-Golang-Gin-and-MongoDB.webp) 145 | 146 | ### Topics Covered 147 | 148 | - Golang, Gin Gonic, MongoDB CRUD RESTful API Overview 149 | - Create the Models with Structs 150 | - Create the Service Interface 151 | - Create Methods to Implement the Interface 152 | - Initialize the Service Struct 153 | - Define a Service to Create a Post 154 | - Define a Service to Update Post 155 | - Define a Service to Delete Post 156 | - Define a Service to Get Single Post 157 | - Define a Service to Get All Posts 158 | - Create Controllers to Perform the CRUD Operations 159 | - Initialize the Controller Struct 160 | - Define a Controller to Create a Post 161 | - Define a Controller to Update a Post 162 | - Define a Controller to Delete a Post 163 | - Define a Controller to Get a Single Post 164 | - Define a Controller to Get All Posts 165 | - Create the Routes for the Controllers 166 | - Initialize the Constructors and Start the Gin Server 167 | 168 | Read the entire article here: [https://codevoweb.com/crud-restful-api-server-with-golang-and-mongodb](https://codevoweb.com/crud-restful-api-server-with-golang-and-mongodb) 169 | 170 | 171 | ## 8. Build CRUD gRPC Server API & Client with Golang and MongoDB 172 | 173 | In this article, you'll learn how to build a CRUD gRPC API server with Golang, MongoDB-Go-driver, and Docker-compose. You'll also build a gRPC client to interact with the gRPC API. 174 | 175 | ![Build CRUD gRPC Server API & Client with Golang and MongoDB](https://codevoweb.com/wp-content/uploads/2022/06/Build-CRUD-gRPC-Server-API-Client-with-Golang-and-MongoDB.webp) 176 | 177 | ### Topics Covered 178 | 179 | - Define the Models with Structs 180 | - Create the ProtoBuf Messages 181 | - Define the gRPC Service and RPC Methods 182 | - Define a Custom Service Interface 183 | - Create Methods to Implement the Service Interface 184 | - Create a Constructor to Implement the Service Interface 185 | - Create a new Post 186 | - Update a Post 187 | - Find a Post 188 | - Retrieve All Posts 189 | - Delete a Post 190 | - Define the gRPC Controllers 191 | - Register the gRPC Services and Start the gRPC Server 192 | - Test the gRPC API Server with Evans CLI 193 | - Create the gRPC API Handlers in Golang 194 | - CreatePost gRPC Handler 195 | - UpdatePost gRPC Service Handler 196 | - GetPost gRPC Service Handler 197 | - DeletePost gRPC Service Handler 198 | - GetPosts gRPC Service Handler 199 | - Testing the gRPC Services with Evans Cli 200 | - Create the gRPC Clients 201 | - gRPC Client to Create a Post 202 | - gRPC Client to Update a Post 203 | - gRPC Client to Get a Single Post 204 | - gRPC Client to Get All Posts 205 | - gRPC Client to Delete a Post 206 | - Register the gRPC Services 207 | 208 | Read the entire article here: [https://codevoweb.com/crud-grpc-server-api-client-with-golang-and-mongodb](https://codevoweb.com/crud-grpc-server-api-client-with-golang-and-mongodb) 209 | -------------------------------------------------------------------------------- /routes/auth.routes.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/wpcodevo/golang-mongodb/controllers" 6 | "github.com/wpcodevo/golang-mongodb/middleware" 7 | "github.com/wpcodevo/golang-mongodb/services" 8 | ) 9 | 10 | type AuthRouteController struct { 11 | authController controllers.AuthController 12 | } 13 | 14 | func NewAuthRouteController(authController controllers.AuthController) AuthRouteController { 15 | return AuthRouteController{authController} 16 | } 17 | 18 | func (rc *AuthRouteController) AuthRoute(rg *gin.RouterGroup, userService services.UserService) { 19 | router := rg.Group("/auth") 20 | 21 | router.POST("/register", rc.authController.SignUpUser) 22 | router.POST("/login", rc.authController.SignInUser) 23 | router.GET("/refresh", rc.authController.RefreshAccessToken) 24 | router.GET("/logout", middleware.DeserializeUser(userService), rc.authController.LogoutUser) 25 | router.GET("/verifyemail/:verificationCode", rc.authController.VerifyEmail) 26 | router.POST("/forgotPassword", rc.authController.ForgotPassword) 27 | } 28 | -------------------------------------------------------------------------------- /routes/post.routes.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/wpcodevo/golang-mongodb/controllers" 6 | ) 7 | 8 | type PostRouteController struct { 9 | postController controllers.PostController 10 | } 11 | 12 | func NewPostControllerRoute(postController controllers.PostController) PostRouteController { 13 | return PostRouteController{postController} 14 | } 15 | 16 | func (r *PostRouteController) PostRoute(rg *gin.RouterGroup) { 17 | router := rg.Group("/posts") 18 | 19 | router.GET("/", r.postController.FindPosts) 20 | router.GET("/:postId", r.postController.FindPostById) 21 | router.POST("/", r.postController.CreatePost) 22 | router.PATCH("/:postId", r.postController.UpdatePost) 23 | router.DELETE("/:postId", r.postController.DeletePost) 24 | } 25 | -------------------------------------------------------------------------------- /routes/user.routes.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/wpcodevo/golang-mongodb/controllers" 6 | "github.com/wpcodevo/golang-mongodb/middleware" 7 | "github.com/wpcodevo/golang-mongodb/services" 8 | ) 9 | 10 | type UserRouteController struct { 11 | userController controllers.UserController 12 | } 13 | 14 | func NewRouteUserController(userController controllers.UserController) UserRouteController { 15 | return UserRouteController{userController} 16 | } 17 | 18 | func (uc *UserRouteController) UserRoute(rg *gin.RouterGroup, userService services.UserService) { 19 | 20 | router := rg.Group("users") 21 | router.Use(middleware.DeserializeUser(userService)) 22 | router.GET("/me", uc.userController.GetMe) 23 | } 24 | -------------------------------------------------------------------------------- /services/auth.service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import "github.com/wpcodevo/golang-mongodb/models" 4 | 5 | type AuthService interface { 6 | SignUpUser(*models.SignUpInput) (*models.DBResponse, error) 7 | SignInUser(*models.SignInInput) (*models.DBResponse, error) 8 | } 9 | -------------------------------------------------------------------------------- /services/auth.service.impl.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "strings" 7 | "time" 8 | 9 | "github.com/wpcodevo/golang-mongodb/models" 10 | "github.com/wpcodevo/golang-mongodb/utils" 11 | "go.mongodb.org/mongo-driver/bson" 12 | "go.mongodb.org/mongo-driver/mongo" 13 | "go.mongodb.org/mongo-driver/mongo/options" 14 | ) 15 | 16 | type AuthServiceImpl struct { 17 | collection *mongo.Collection 18 | ctx context.Context 19 | } 20 | 21 | func NewAuthService(collection *mongo.Collection, ctx context.Context) AuthService { 22 | return &AuthServiceImpl{collection, ctx} 23 | } 24 | 25 | func (uc *AuthServiceImpl) SignUpUser(user *models.SignUpInput) (*models.DBResponse, error) { 26 | user.CreatedAt = time.Now() 27 | user.UpdatedAt = user.CreatedAt 28 | user.Email = strings.ToLower(user.Email) 29 | user.PasswordConfirm = "" 30 | user.Verified = false 31 | user.Role = "user" 32 | 33 | hashedPassword, _ := utils.HashPassword(user.Password) 34 | user.Password = hashedPassword 35 | res, err := uc.collection.InsertOne(uc.ctx, &user) 36 | 37 | if err != nil { 38 | if er, ok := err.(mongo.WriteException); ok && er.WriteErrors[0].Code == 11000 { 39 | return nil, errors.New("user with that email already exist") 40 | } 41 | return nil, err 42 | } 43 | 44 | // Create a unique index for the email field 45 | opt := options.Index() 46 | opt.SetUnique(true) 47 | index := mongo.IndexModel{Keys: bson.M{"email": 1}, Options: opt} 48 | 49 | if _, err := uc.collection.Indexes().CreateOne(uc.ctx, index); err != nil { 50 | return nil, errors.New("could not create index for email") 51 | } 52 | 53 | var newUser *models.DBResponse 54 | query := bson.M{"_id": res.InsertedID} 55 | 56 | err = uc.collection.FindOne(uc.ctx, query).Decode(&newUser) 57 | if err != nil { 58 | return nil, err 59 | } 60 | 61 | return newUser, nil 62 | } 63 | 64 | func (uc *AuthServiceImpl) SignInUser(*models.SignInInput) (*models.DBResponse, error) { 65 | return nil, nil 66 | } 67 | -------------------------------------------------------------------------------- /services/post.service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import "github.com/wpcodevo/golang-mongodb/models" 4 | 5 | type PostService interface { 6 | CreatePost(*models.CreatePostRequest) (*models.DBPost, error) 7 | UpdatePost(string, *models.UpdatePost) (*models.DBPost, error) 8 | FindPostById(string) (*models.DBPost, error) 9 | FindPosts(page int, limit int) ([]*models.DBPost, error) 10 | DeletePost(string) error 11 | } 12 | -------------------------------------------------------------------------------- /services/post.service.impl.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "time" 7 | 8 | "github.com/wpcodevo/golang-mongodb/models" 9 | "github.com/wpcodevo/golang-mongodb/utils" 10 | "go.mongodb.org/mongo-driver/bson" 11 | "go.mongodb.org/mongo-driver/bson/primitive" 12 | "go.mongodb.org/mongo-driver/mongo" 13 | "go.mongodb.org/mongo-driver/mongo/options" 14 | ) 15 | 16 | type PostServiceImpl struct { 17 | postCollection *mongo.Collection 18 | ctx context.Context 19 | } 20 | 21 | func NewPostService(postCollection *mongo.Collection, ctx context.Context) PostService { 22 | return &PostServiceImpl{postCollection, ctx} 23 | } 24 | 25 | func (p *PostServiceImpl) CreatePost(post *models.CreatePostRequest) (*models.DBPost, error) { 26 | post.CreateAt = time.Now() 27 | post.UpdatedAt = post.CreateAt 28 | res, err := p.postCollection.InsertOne(p.ctx, post) 29 | 30 | if err != nil { 31 | if er, ok := err.(mongo.WriteException); ok && er.WriteErrors[0].Code == 11000 { 32 | return nil, errors.New("post with that title already exists") 33 | } 34 | return nil, err 35 | } 36 | 37 | opt := options.Index() 38 | opt.SetUnique(true) 39 | 40 | index := mongo.IndexModel{Keys: bson.M{"title": 1}, Options: opt} 41 | 42 | if _, err := p.postCollection.Indexes().CreateOne(p.ctx, index); err != nil { 43 | return nil, errors.New("could not create index for title") 44 | } 45 | 46 | var newPost *models.DBPost 47 | query := bson.M{"_id": res.InsertedID} 48 | if err = p.postCollection.FindOne(p.ctx, query).Decode(&newPost); err != nil { 49 | return nil, err 50 | } 51 | 52 | return newPost, nil 53 | } 54 | 55 | func (p *PostServiceImpl) UpdatePost(id string, data *models.UpdatePost) (*models.DBPost, error) { 56 | doc, err := utils.ToDoc(data) 57 | if err != nil { 58 | return nil, err 59 | } 60 | 61 | obId, _ := primitive.ObjectIDFromHex(id) 62 | query := bson.D{{Key: "_id", Value: obId}} 63 | update := bson.D{{Key: "$set", Value: doc}} 64 | res := p.postCollection.FindOneAndUpdate(p.ctx, query, update, options.FindOneAndUpdate().SetReturnDocument(1)) 65 | 66 | var updatedPost *models.DBPost 67 | if err := res.Decode(&updatedPost); err != nil { 68 | return nil, errors.New("no post with that Id exists") 69 | } 70 | 71 | return updatedPost, nil 72 | } 73 | 74 | func (p *PostServiceImpl) FindPostById(id string) (*models.DBPost, error) { 75 | obId, _ := primitive.ObjectIDFromHex(id) 76 | 77 | query := bson.M{"_id": obId} 78 | 79 | var post *models.DBPost 80 | 81 | if err := p.postCollection.FindOne(p.ctx, query).Decode(&post); err != nil { 82 | if err == mongo.ErrNoDocuments { 83 | return nil, errors.New("no document with that Id exists") 84 | } 85 | 86 | return nil, err 87 | } 88 | 89 | return post, nil 90 | } 91 | 92 | func (p *PostServiceImpl) FindPosts(page int, limit int) ([]*models.DBPost, error) { 93 | if page == 0 { 94 | page = 1 95 | } 96 | 97 | if limit == 0 { 98 | limit = 10 99 | } 100 | 101 | skip := (page - 1) * limit 102 | 103 | opt := options.FindOptions{} 104 | opt.SetLimit(int64(limit)) 105 | opt.SetSkip(int64(skip)) 106 | opt.SetSort(bson.M{"created_at": -1}) 107 | 108 | query := bson.M{} 109 | 110 | cursor, err := p.postCollection.Find(p.ctx, query, &opt) 111 | if err != nil { 112 | return nil, err 113 | } 114 | 115 | defer cursor.Close(p.ctx) 116 | 117 | var posts []*models.DBPost 118 | 119 | for cursor.Next(p.ctx) { 120 | post := &models.DBPost{} 121 | err := cursor.Decode(post) 122 | 123 | if err != nil { 124 | return nil, err 125 | } 126 | 127 | posts = append(posts, post) 128 | } 129 | 130 | if err := cursor.Err(); err != nil { 131 | return nil, err 132 | } 133 | 134 | if len(posts) == 0 { 135 | return []*models.DBPost{}, nil 136 | } 137 | 138 | return posts, nil 139 | } 140 | 141 | func (p *PostServiceImpl) DeletePost(id string) error { 142 | obId, _ := primitive.ObjectIDFromHex(id) 143 | query := bson.M{"_id": obId} 144 | 145 | res, err := p.postCollection.DeleteOne(p.ctx, query) 146 | if err != nil { 147 | return err 148 | } 149 | 150 | if res.DeletedCount == 0 { 151 | return errors.New("no document with that Id exists") 152 | } 153 | 154 | return nil 155 | } 156 | -------------------------------------------------------------------------------- /services/user.service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import "github.com/wpcodevo/golang-mongodb/models" 4 | 5 | type UserService interface { 6 | FindUserById(id string) (*models.DBResponse, error) 7 | FindUserByEmail(email string) (*models.DBResponse, error) 8 | UpdateUserById(id string, data *models.UpdateInput) (*models.DBResponse, error) 9 | } 10 | -------------------------------------------------------------------------------- /services/user.service.impl.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "strings" 8 | 9 | "github.com/wpcodevo/golang-mongodb/models" 10 | "github.com/wpcodevo/golang-mongodb/utils" 11 | "go.mongodb.org/mongo-driver/bson" 12 | "go.mongodb.org/mongo-driver/bson/primitive" 13 | "go.mongodb.org/mongo-driver/mongo" 14 | "go.mongodb.org/mongo-driver/mongo/options" 15 | ) 16 | 17 | type UserServiceImpl struct { 18 | collection *mongo.Collection 19 | ctx context.Context 20 | } 21 | 22 | func NewUserServiceImpl(collection *mongo.Collection, ctx context.Context) UserService { 23 | return &UserServiceImpl{collection, ctx} 24 | } 25 | 26 | func (us *UserServiceImpl) FindUserById(id string) (*models.DBResponse, error) { 27 | oid, _ := primitive.ObjectIDFromHex(id) 28 | 29 | var user *models.DBResponse 30 | 31 | query := bson.M{"_id": oid} 32 | err := us.collection.FindOne(us.ctx, query).Decode(&user) 33 | 34 | if err != nil { 35 | if err == mongo.ErrNoDocuments { 36 | return &models.DBResponse{}, err 37 | } 38 | return nil, err 39 | } 40 | 41 | return user, nil 42 | } 43 | 44 | func (us *UserServiceImpl) FindUserByEmail(email string) (*models.DBResponse, error) { 45 | var user *models.DBResponse 46 | 47 | query := bson.M{"email": strings.ToLower(email)} 48 | err := us.collection.FindOne(us.ctx, query).Decode(&user) 49 | 50 | if err != nil { 51 | if err == mongo.ErrNoDocuments { 52 | return &models.DBResponse{}, err 53 | } 54 | return nil, err 55 | } 56 | 57 | return user, nil 58 | } 59 | 60 | func (uc *UserServiceImpl) UpdateUserById(id string, data *models.UpdateInput) (*models.DBResponse, error) { 61 | doc, err := utils.ToDoc(data) 62 | if err != nil { 63 | return &models.DBResponse{}, err 64 | } 65 | 66 | fmt.Println(data) 67 | 68 | obId, _ := primitive.ObjectIDFromHex(id) 69 | 70 | query := bson.D{{Key: "_id", Value: obId}} 71 | update := bson.D{{Key: "$set", Value: doc}} 72 | result := uc.collection.FindOneAndUpdate(uc.ctx, query, update, options.FindOneAndUpdate().SetReturnDocument(1)) 73 | 74 | var updatedUser *models.DBResponse 75 | if err := result.Decode(&updatedUser); err != nil { 76 | return nil, errors.New("no document with that id exists") 77 | } 78 | 79 | return updatedUser, nil 80 | } 81 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | {{define "base"}} 2 | 3 | 4 | 5 | 6 | 7 | {{template "styles" .}} 8 | {{ .Subject}} 9 | 10 | 11 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | {{end}} 33 | -------------------------------------------------------------------------------- /templates/resetPassword.html: -------------------------------------------------------------------------------- 1 | {{template "base" .}} {{define "content"}} 2 | 3 | 4 | 5 | 50 | 51 | 52 | 53 | 54 | {{end}} 55 | -------------------------------------------------------------------------------- /templates/styles.html: -------------------------------------------------------------------------------- 1 | {{define "styles"}} 2 | 331 | {{end}} 332 | -------------------------------------------------------------------------------- /templates/verificationCode.html: -------------------------------------------------------------------------------- 1 | {{template "base" .}} {{define "content"}} 2 | 3 | 4 | 5 | 46 | 47 | 48 | 49 | 50 | {{end}} 51 | -------------------------------------------------------------------------------- /utils/email.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "crypto/tls" 6 | "fmt" 7 | "log" 8 | "os" 9 | "path/filepath" 10 | "text/template" 11 | 12 | "github.com/k3a/html2text" 13 | "github.com/wpcodevo/golang-mongodb/config" 14 | "github.com/wpcodevo/golang-mongodb/models" 15 | "gopkg.in/gomail.v2" 16 | ) 17 | 18 | type EmailData struct { 19 | URL string 20 | FirstName string 21 | Subject string 22 | } 23 | 24 | // 👇 Email template parser 25 | 26 | func ParseTemplateDir(dir string) (*template.Template, error) { 27 | var paths []string 28 | err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 29 | if err != nil { 30 | return err 31 | } 32 | if !info.IsDir() { 33 | paths = append(paths, path) 34 | } 35 | return nil 36 | }) 37 | 38 | fmt.Println("Am parsing templates...") 39 | 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | return template.ParseFiles(paths...) 45 | } 46 | 47 | func SendEmail(user *models.DBResponse, data *EmailData, templateName string) error { 48 | config, err := config.LoadConfig(".") 49 | 50 | if err != nil { 51 | log.Fatal("could not load config", err) 52 | } 53 | 54 | // Sender data. 55 | from := config.EmailFrom 56 | smtpPass := config.SMTPPass 57 | smtpUser := config.SMTPUser 58 | to := user.Email 59 | smtpHost := config.SMTPHost 60 | smtpPort := config.SMTPPort 61 | 62 | var body bytes.Buffer 63 | 64 | template, err := ParseTemplateDir("templates") 65 | if err != nil { 66 | log.Fatal("Could not parse template", err) 67 | } 68 | 69 | template = template.Lookup(templateName) 70 | template.Execute(&body, &data) 71 | fmt.Println(template.Name()) 72 | 73 | m := gomail.NewMessage() 74 | 75 | m.SetHeader("From", from) 76 | m.SetHeader("To", to) 77 | m.SetHeader("Subject", data.Subject) 78 | m.SetBody("text/html", body.String()) 79 | m.AddAlternative("text/plain", html2text.HTML2Text(body.String())) 80 | 81 | d := gomail.NewDialer(smtpHost, smtpPort, smtpUser, smtpPass) 82 | d.TLSConfig = &tls.Config{InsecureSkipVerify: true} 83 | 84 | // Send Email 85 | if err := d.DialAndSend(m); err != nil { 86 | return err 87 | } 88 | return nil 89 | } 90 | -------------------------------------------------------------------------------- /utils/encode.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "encoding/base64" 4 | 5 | func Encode(s string) string { 6 | data := base64.StdEncoding.EncodeToString([]byte(s)) 7 | return string(data) 8 | } 9 | 10 | func Decode(s string) (string, error) { 11 | data, err := base64.StdEncoding.DecodeString(s) 12 | if err != nil { 13 | return "", err 14 | } 15 | 16 | return string(data), nil 17 | } 18 | -------------------------------------------------------------------------------- /utils/helper.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "go.mongodb.org/mongo-driver/bson" 4 | 5 | func ToDoc(v interface{}) (doc *bson.D, err error) { 6 | data, err := bson.Marshal(v) 7 | if err != nil { 8 | return 9 | } 10 | 11 | err = bson.Unmarshal(data, &doc) 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /utils/password.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | 6 | "golang.org/x/crypto/bcrypt" 7 | ) 8 | 9 | func HashPassword(password string) (string, error) { 10 | hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) 11 | 12 | if err != nil { 13 | return "", fmt.Errorf("could not hash password %w", err) 14 | } 15 | return string(hashedPassword), nil 16 | } 17 | 18 | func VerifyPassword(hashedPassword string, candidatePassword string) error { 19 | return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(candidatePassword)) 20 | } 21 | -------------------------------------------------------------------------------- /utils/token.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/golang-jwt/jwt" 9 | ) 10 | 11 | func CreateToken(ttl time.Duration, payload interface{}, privateKey string) (string, error) { 12 | decodedPrivateKey, err := base64.StdEncoding.DecodeString(privateKey) 13 | if err != nil { 14 | return "", fmt.Errorf("could not decode key: %w", err) 15 | } 16 | key, err := jwt.ParseRSAPrivateKeyFromPEM(decodedPrivateKey) 17 | 18 | if err != nil { 19 | return "", fmt.Errorf("create: parse key: %w", err) 20 | } 21 | 22 | now := time.Now().UTC() 23 | 24 | claims := make(jwt.MapClaims) 25 | claims["sub"] = payload 26 | claims["exp"] = now.Add(ttl).Unix() 27 | claims["iat"] = now.Unix() 28 | claims["nbf"] = now.Unix() 29 | 30 | token, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key) 31 | 32 | if err != nil { 33 | return "", fmt.Errorf("create: sign token: %w", err) 34 | } 35 | 36 | return token, nil 37 | } 38 | 39 | func ValidateToken(token string, publicKey string) (interface{}, error) { 40 | decodedPublicKey, err := base64.StdEncoding.DecodeString(publicKey) 41 | if err != nil { 42 | return nil, fmt.Errorf("could not decode: %w", err) 43 | } 44 | 45 | key, err := jwt.ParseRSAPublicKeyFromPEM(decodedPublicKey) 46 | 47 | if err != nil { 48 | return "", fmt.Errorf("validate: parse key: %w", err) 49 | } 50 | 51 | parsedToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { 52 | if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok { 53 | return nil, fmt.Errorf("unexpected method: %s", t.Header["alg"]) 54 | } 55 | return key, nil 56 | }) 57 | 58 | if err != nil { 59 | return nil, fmt.Errorf("validate: %w", err) 60 | } 61 | 62 | claims, ok := parsedToken.Claims.(jwt.MapClaims) 63 | if !ok || !parsedToken.Valid { 64 | return nil, fmt.Errorf("validate: invalid token") 65 | } 66 | 67 | return claims["sub"], nil 68 | } 69 | --------------------------------------------------------------------------------