En la segunda parte de nuestra serie de artículos "Escribir un blog en microservicios", describimos
la API Gateway .
Aquí describimos la implementación del microservicio de usuario.
Nuestro microservicio debería poder:
- Registre las llamadas de servicio y los estados intermedios que indican TraceId (el mismo emitido por api-gw, consulte la Parte 2 "API Gateway" )
- Implemente las funciones de inicio de sesión (SignIN) y registro (SignUp)
- Implemente funciones CRUD (crear, leer, editar, eliminar registros en la base de datos). Use MongoDB como la base de datos.
Primero, describimos nuestro servicio en el archivo proto (./services/user/protobuf/user.proto).
Especifique la sintaxis utilizada: proto3. Indicamos el nombre del paquete protobuf, en este paquete se implementará el código autogenerado del servidor y las partes del cliente.
Importamos la biblioteca de anotaciones google / api / annotations.proto, será necesario describir las directivas para generar la API REST.
syntax = "proto3"; package protobuf; import "google/api/annotations.proto";
Descripción del servicio de usuario, directamente las interfaces (métodos) que debería tener. Por ejemplo, la interfaz SignUp (registro): recibe un mensaje SignUpRequest que contiene los atributos Nombre de usuario, Contraseña, Nombre y Apellido y responde con un mensaje SignUpResponse que contiene los atributos Slug (UserID), Nombre de usuario, Rol. También en la descripción de la interfaz, en la sección de opciones, especifique la directiva de publicación: "/ api / v1 / user / signup. En función de esto, el generador de código creará una interfaz REST que recibirá solicitudes POST en http: {{api_gw_host}} / api / v1 / user / registro.
Y esperará la siguiente estructura en el cuerpo de la solicitud:
{ Username: 'username_value', Password: 'password_value', FirstName: 'firstname_value', LastName: 'lastname_value', }
Y en consecuencia, si tiene éxito, dará la estructura:
{ Slug: 'user_id_value', Username: 'username_value', Role: 'role_value', }
O un error. Le informaremos más sobre los errores un poco más adelante en la sección que describe las funciones que implementan las interfaces descritas en el protofile.
Otras interfaces (Iniciar sesión, Crear, Actualizar, Eliminar, Obtener, Buscar) se declaran de la misma manera.
Ahora que tenemos un protofile listo para usar. Vamos al directorio raíz del proyecto y ejecutamos el comando sh ./bin/protogen.sh. Este script generará el código principal.
A continuación, vaya al directorio ./services/user y en el archivo functions.go escriba la implementación de las interfaces declaradas.
Primero, implementamos middleware. En cada solicitud al servicio, extraemos los parámetros TraceId, UserId, UserRole del contexto de solicitud y los escribimos en el archivo de registro. Aquí puede implementar la autorización de solicitud.
En el método SignUp, determinamos la estructura de respuesta.
A continuación, verifique los parámetros de la solicitud.
Y si todo está bien, complete la estructura del Usuario, escriba en la base de datos y devuelva la respuesta.
user:=&User{ Username:in.Username, FirstName:in.FirstName, LastName:in.LastName, Password:getMD5(in.Password), } var slug string collection:= o.DbClient.Database("blog").Collection("users") insertResult, err := collection.InsertOne(context.TODO(), user) if err != nil { return out,err } if oid, ok := insertResult.InsertedID.(primitive.ObjectID); ok { slug=fmt.Sprintf("%s",oid.Hex()) }else { err:=app.ErrInsert return out,err } out.Slug=slug out.Username=in.Username out.Role=app.ROLE_USER return out,nil
Por separado, prestamos atención al error de retorno, por ejemplo:
err:=app.ErrInsert
Dado que, en última instancia, este error volverá a nuestro api-wg (en su parte REST) y sería genial convertirlo a un código de respuesta HTTP estándar. Para no escribir un montón de código adicional, no debe usar el error estándar go, sino status.error del paquete google.golang.org/grpc/status.
Todos los errores típicos del microservicio del usuario y cómo se convierten en códigos de respuesta HTTP se describen en el archivo / Services / user / app / errors.go.
package app import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" )
Y lo último que me gustaría contar sobre el microservicio de usuario es cómo se inicia y se conecta a la base de datos. Estas operaciones se realizan en el archivo ./services/user/main.go.
Lanzamiento de servicio:
lis,err:= net.Listen("tcp", fmt.Sprintf(":%s", Port)) if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer:= grpc.NewServer( grpc.UnaryInterceptor(protobuf.AccessLogInterceptor), ) s:=&protobuf.Server{} …
Conexión a la base de datos (main.go):
Implementación de la función DbConnect (./services/user/functions.go):