Categorygithub.com/validatecl/go-microservices-commons
modulepackage
1.0.14
Repository: https://github.com/validatecl/go-microservices-commons.git
Documentation: pkg.go.dev

# README

Go Microservices commons

pipelinecoverage

Componentes comunes de microservicios desarrolados con gokit

Errores comunes y su manejo

Microservices commons trae variados errores comunes de los servicios que desarrollamos, estos distintos tipos de errores son manejados a nivel de transporte http por Error2Wrapper el cual permite manejar estos errores comunes y retornar un struct con un status code correspondiente al error, ejemplo:

{
    "code": "400",
    "message": "Datos de entrada no válidos.",
    "docs": "https://developerportal.apigee.io/apis/{apidoc}"
}
ErrorStatusObs
InputError400
ServiceError500
GatewayError503
BackendCodedError502Errores de Backend con codigos de error

Personalizacion de DOCS URL

Para personalizar contenido de docs en response de error debe modificarse la variable DOCSURL del package, ejemplo:

DOCSURL = "https://developerportal.apigee.io/apis/{apidoc}"

HTTP Transport response encoder

Se agrego tambien una funcion default para Encoding de response http que en combinacion con el Error2Wrapper mencionado en el punto anterior. Esta funcion EncodeHTTPResponseFunc posterior a ser creada con MakeEncodeHTTPResponseFunc puede ser usada como argumento como funcion de EncodeResponse al momento de crear un http server. para referencias ver tests

Default Endpoint y sus middlewares

Se provee de una funcion middleware MakeDefaultEntryEndpoint para crear endpoint por defecto al cual se decora con los siguientes middlewares:

MiddlewareObs
EndpointLogMiddlewareLoguea operacion, tiempo de inicio, tiempo que tomo la request y errores

Creacion de http handler

Se provee de un builder para inicializar un http handler el cual inicializa endpoints y aplica mapping de errores, middlewares de tracing y logging al server y a los endpoints provistos.

Antes de inicializar el service es necesario crear la configuracion de nuestro endpoint indicando path, nombre de operacion, endpoint, request decoder y response encoder.

endpointCfgs := []commons.EndpointConfig{
	commons.GET("/drink/beer", "DRINK_BEER", beerEndpoint, decoder, nil),
}

Nota 1: En el ejemplo el ultimo argumento "response encoder" esta nil, de este modo utiliza el response encoder por defecto, este argumento solo debe ser utilizado en caso de requerir personalizar response.

Nota 2: En el ejemplo se llama a la funcion GET pero tambien estan disponibles POST, PUT, PATCH y DELETE.

Luego simplemente creamos nuestro http handler con el builder:

commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).Build()

Si queremos un manejo de errores personalizado podemos crear un middleware o una funcion personalizada para manejo de errores, para esto se provee de un modificador para el builder WithCustomErrorWrapper:

commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).WithCustomErrorWrapper(errWrapperFunc).Build()

Para habilitar el tracing es necesario utilizar el modificador WithTracer para setear un tracer del tipo Tracer de "github.com/opentracing/opentracing-go"

commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).WithTracer(tracer).Build()

Para habilitar instrumentacion de similar modo se puede agregar generando metricas por defecto y utilizando el modificador ``

metrics := commons.MakeDefaultEndpointMetrics("integration", "beer_service")

handler := commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).WithMetrics(metrics).Build()

Para personalizar el context a partir de la request se puede usar un RequestFuncMiddleware primero se crea un middleware func

func makeCustomRequestFuncMiddleware() RequestFuncMiddleware {
    return func(next httptransport.RequestFunc) httptransport.RequestFunc {
        return func(ctx context.Context, req *http.Request) context.Context {
            superHeaderValue := req.Header.Get("super-value")
            ctx = context.WithValue(ctx, "special-key", superHeaderValue)
            
            return next(ctx, req)
        }
    }
}

Para luego setearse en el builder

handler := commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).WithCustomRequestFuncMiddleware(makeCustomRequestFuncMiddleware()).Build()

Obviamente estas configuraciones se pueden combinar

commons.MakeHTTPHandlerBuilder(logger, endpointCfgs).WithTracer(tracer).WithCustomErrorWrapper(errWrapperFunc).Build()

Creacion de Logger

Para crear un nuevo logger se debe llamar a la funcion ConfigureLogger indicando el nivel de logger, los niveles disponibles son debug, info, warn y error.

logger := c.ConfigureLogger("info")

Creacion de Server

Para crea un server (group) se debe utilizar la funcion CreateServer pasando como argumento un http.Handler, port y logger.

g := c.CreateServer(handler, ":8080", logger)
logger.Log("exit", g.Run())

Middlewares utilitarios

Cache

Se ha provisto de una implementacion de endpoint cache middleware utilizando gcache. Para decorar un endpoint con este middleware se debe crear indicando una funcion keyResolver el cual pueda crear una key a partir de la interfaz que se utilice como argumento, cache size y un ttl.

type Person struct{
    Name string
    Age string
}

func resolvePersonKey(in interface{}) string {
    person := in.(*Person)

    return fmt.Sprintf(%s-%d, person.Name, person.Age)
}

...
ep = commons.MakeCacheEndpointMiddleware(resolvePersonKey, 20, time.Minute * 15)(serviceEndpoint)

HTTP client

Para crea un nuevo http client se debe utilizar el http client builder.

commons.MakeHTTPClientBuilder("http://servicehost/requestpath",
		"POST",
		time.Second,
		encodeRequest,
		decodeResponse,
		log.NewNopLogger()).
		Build()

Adicional a esto el builder tiene un metodo para crear un client que utilice opentracing

commons.MakeHTTPClientBuilder("http://servicehost/requestpath",
		"POST",
		time.Second,
		encodeRequest,
		decodeResponse,
		log.NewNopLogger()).
        WithTracer(tracer).
		Build()

Client: Default Request encoder

Se puede utilizar un default request encoder para client que convierte cualquier struct a json.

commons.DefaultRequestEncode

Client: Default Response decoder

Se puede utilizar un default response decoder que simplemente requiere inicializar el puntero a la estructura.

func CustomDecode(ctx context.Context, r *http.Response) (interface{}, error) {
	return commons.DefaultDecodeResponse(ctx, r, new(entity.MyClientResponseStruct))
}

Client Credentials OAUTH client y Request encode middleware

De ser necesario de autenticarse por OAuth se provee de dos componentes.

Auth Client (o endpoint) permite llamar a una api de autenticacion oauth con grant type client_credentials de modo de obtener un token de acceso.

authClient := commons.MakeClientCredentialsOAUTHClient("http://authme.plz", "clientID", "clientSecret", time.Second, logger)

Donde authClient es un endpoint que llamara a la API de autenticacion y retornara un TokenResponse.

Adicional a esto se ha provisto de un middleware para clients http, el cual permite inyectar el header de Authorization utilizando este AuthClient.

myEncodeRequestFunc := commons.MakeOAuthClientCredentialsRequestEncodeMiddleware(authClient)(commons.DefaultRequestEncode)

Paginacion

Para Paginacion solo se proveen las estructuras necesarias para implementar paginacion con el fin de ser reutilizadas para implementar paginacion.

Ver paging.go

Validate Middleware

Validar struct, se está validando por los siguientes Tag

  • required (Los siguientes campos son requeridos: X-channel)
  • oneof (Los siguientes campos no hacen match con el enumerado: X-channel)
  • min (Los siguientes campos no cumplen con el mínimo de caracteres: X-channel)
  • default "Cualquier otra validate que no tenemos controlado"(Los siguientes campos son inválidos: X-channel)

Implementar el método de la siguiente forma dentro del endpoint myEndpoint = commons.ValidateMiddleware()(myEndpoint)

# Functions

ConfigureLogger configura un JSON logger por defecto con levels habilitados debug, info, warn, error.
CreateServer inicializa un http server.
DecodeAuthResponse decode de response de auth.
DefaultDecodeResponse decode de response por defecto, para utilizar referenciar dependencias.
DefaultRequestEncode encode de request de client.
DELETE crea un DELETE endpoint config.
EndpointHTTPTimeTakenMetricsMiddleware middleware de metrics para tiempo que tomo la peticion HTTP.
EndpointLogMiddleware loguea tiempo que tomo servir request y error si es que hubo alguno.
EndpointSuccesAndFailureMetricsMiddleware middleware de metrics de success y failures.
EndpointTimeTakenMetricsMiddleware middleware de metrics para tiempo que tomo la peticion.
Error2Status Convierte errores en status HTTP.
Error2Wrapper Convierte error a status code y error wrapper.
GET crea un GET endpoint config - Parametro Response Encoder es opcional.
HTTPToContextOnce http context or span.
MakeCacheEndpointMiddleware crea un middleware de cache.
MakeClientCredentialsOAUTHClient Crea cliente de autenticacion.
MakeDefaultEncodeHTTPResponseFunc default http response encoder.
MakeDefaultEndpointMetrics crea metricas por defecto para endpoint middleware de metricas.
MakeDefaultEntryEndpoint endpoint middleware por defecto.
MakeDefaultServerErrorEncoderFunc default error encoder.
MakeEncodeClientCredentialsAuthRequest crea encode de auth request.
MakeEncodeHTTPResponseFunc crea encode function.
MakeHTTPClientBuilder crea un nuevo http client builder.
MakeHTTPHandlerBuilder crea un http server builder.
MakeOAuthClientCredentialsRequestEncodeMiddleware crea middleware para encodeRequest.
MakeServerErrorEncoderFunc funcion de encode de errores.
NewErrorWrapper crea un nuevo error wrapper.
NewErrorWrapperWM crea un nuevo error wrapper.
NewPagingRequest nuevo paging request.
NewPagingResponse nuevo paging response.
PATCH crea un PATCH endpoint config - Parametro Response Encoder es opcional.
POST
POST crea un POST endpoint config - Parametro Response Encoder es opcional.
PUT crea un PUT endpoint config - Parametro Response Encoder es opcional.
StringPointer .
UnmarshalError2Wrapper Convierte el error del Unmarshal a su equivalente HTTP.
ValidateMiddleware Validate middleware endpoint.

# Constants

No description provided by the author

# Variables

DOCSURL variable para setear DOCS de response.

# Structs

AuthResponse response.
BackendCodedError errores codificados de backend.
BadGatewayError error de service externo.
CustomError errores customizables.
EndpointConfig entrada de endpoint.
No description provided by the author
ErrorWrapper wrapper de response error.
ErrorWrapperWM wrapper de response error WM.
GatewayError error de service externo.
InputError error de input de services.
MetricsConfig configuracion de metricas para endpoints.
NotFoundError errores codificados de backend.
Pagination atributos de paginacion.
PagingRequest request de paginacion.
PagingResponse response de paginacion.
ServiceError error de services.
WMError .

# Interfaces

HTTPClientBuilder builder de http client.
HTTPHandlerBuilder builder para httpServer.

# Type aliases

Error2WrapperFunc tipo de funcion error2Wrapper.
Error2WrapperMiddleware middleware de error2WrapperFunc.
KeyResolver funcion que obtiene una key (string) a partir de un interface.
RequestFuncMiddleware Middleware de funcion para actualizar context a partir de una request http.