# Micro servicios v2.2.0

El micro servicio hereda de _Worker_ o _Fork_ dependiendo del elemento que se quiera crear,
se tiene soporte para el broker NATS.

> ## NOTA
>
> Para la seleccion del brocker (kafka, Nats) se debe pasar la variable de ambiente
> que contenga la lista de los servidores del cluster del broker ejemplo:
> KAFKA=servidor,servidor2,servidor3 "o" NATS=servidor,servidor2,servidor3

> ## NOTAS.
>
> Las posibles acciones que tienen un micro servicio son:
>
> - List
> - Create
> - Get
> - Update
> - Delete
>
> Esta son definidas utilizando decoradores tal como se muestra en el ejemplo.

### Ejemplo:

```typescript
import { ErrorMs, Microservice, MsManager } from '@coppel/microservices';

@MsManager.define({
    App: 'NombreApp',
    Name: 'NombreWorker',
    Version: 'v1',
    Broker: ['127.0.0.1:9092'],
    Debug: true
})
class MiWorker extends Microservice {

    /**
     * Metodo de smoketest
     */
    public smoketest(): boolean | Promise<boolean> {
        // Retornar la promesa
        return new Promise( ( rr: (r: boolean) => void, ff: (r: boolean) => void ) => {
            rr(true);
        });
    }

    /**
     *  Errores que puede tener el servicio.
     */
    @MsManager.Errors()
    public errores(): ErrorMs {
        return {
            '-12': 'Error definido por el usuario',
        };
    }

    // Para recuperar cierta informacion se utilizan los siguientes parametros, y colocas nada mas lo que requieras
    // @MsManager.ctx('data') data: any
    // @MsManager.ctx('uuid') id: any
    // @MsManager.ctx('authorization') auth: any
    // @MsManager.ctx('response') resp: any

    @MsManager.List()
    public metodoList(@MsManager.ctx('uuid') id: any, @MsManager.ctx('authorization') auth: any): any {
        // Listar
    }

    @MsManager.Create()
    public crear(@MsManager.ctx('data') data: any, @MsManager.ctx('authorization') auth: any): any {
        // Registrar
    }

    @MsManager.Get()
    public recuperar(@MsManager.ctx('uuid') id: any, @MsManager.ctx('authorization') auth: any): any {
        // Recuperar un elemento
    }

    @MsManager.Update()
    public actualizar(@MsManager.ctx('data') data: any, @MsManager.ctx('uuid') id: any, @MsManager.ctx('authorization') auth: any): any {
        // Actualizar un elemento
    }

    @MsManager.Delete(@MsManager.ctx('uuid') id: any, @MsManager.ctx('authorization') auth: any)
    public eliminar(data: any, auth: boolean, id: any): any {
        // Eliminar un elemento
    }

}

```

> ### NOTAS:
>
> Las clases son auto ejecutables, no se requiere que se implemente una inicializacio/start o similar para poner en marcha el servicio.
>
> Para la indicacion de la cola de mensajes se utiliza la variable de ambiente _KAFKA_.

## Diseño Legado.

Si lo que se quiere es crear un micro servicio basado en el diseño de la version v1.* se utiliza la definicion de *Listener\*, como se indica en el siguiente ejemplo:

```typescript
import { ErrorMs, Microservice, MsManager } from "@coppel/microservices";

@Ms.define({
  App: "NombreApp",
  Name: "NombreWorker",
  Version: "v1",
  Broker: ["127.0.0.1:9092"],
  Debug: true
})
class MiWorker extends Microservice {
  /**
   * Metodo de smoketest
   */
  public smoketest(): boolean | Promise<boolean> {
    // Retornar la promesa
    return new Promise((rr: (r: boolean) => void, ff: (r: boolean) => void) => {
      rr(true);
    });
  }

  /**
   *  Errores que puede tener el servicio.
   */
  @MsManager.Errors()
  public errores(): ErrorMs {
    return {
      "-12": "Error definido por el usuario"
    };
  }

  @MsManager.Listener()
  public metodoList(
    @MsManager.ctx("data") data: any,
    @MsManager.ctx("authorization") auth: any
  ): any {
    // Escuchar todos los eventos
  }
}
```

## Retorno de valores

Para retornar una respuesta simplemente se debe regresar el valor de la funcion:

```typescript
  @MsManager.Get()
  public miFuncion(@MsManager.ctx('data') data: any, @MsManager.ctx('authorization') auth: any): object {
       // Retorno de un objeto
       return {
           Clave: 'Valor',
       };
   }
```

> ### NOTAS:
>
> En caso de que se requiera regresar un valor con una promesa:
>
> ```typescript
>   @MsManager.Get()
>   public miFuncion(@MsManager.ctx('data') data: any, @MsManager.ctx('authorization') auth: any): Promise<object> {
>       // Retornar la promesa
>       return new Promise( (resolve: any, fail: any) => {
>           resolve({ Clave: 'Valor' });
>       });
>   }
> ```
>
> El core detecta la promesa, y espera que se resuelva para retornar la respuesta a la peticion inicial.

## Errores

Para la notificacion de errores, se implementa la utilizada por el lenguaje, llamando a la propiedad heredada Errors, como muestra el ejemplo.

```typescript
  @MsManager.Get()
  public miFuncion(@MsManager.ctx('data') data: any, @MsManager.ctx('authorization') auth: any): object {
       // Ejecutar el error.
       throw this.emitError('-34'); // definido antes.
   }
```

Esto ejecutara la excepcion que es escuchada, por el core, notificando a la peticion original.

> ### NOTAS:
>
> Cuando se utiliza una promesa se puede implementar el llamdo a la excepcion como el ejemplo anterior o de la siguiente manera.
>
> ```typescript
>   @MS.Get()
>   public miFuncion(@MsManager.ctx('data') data: any, @MsManager.ctx('authorization') auth: any): Promise<object> {
>       // Retornar la promesa
>       return new Promise( (resolve: any, fail: any) => {
>           fail(this.emitError('-34'));
>       });
>   }
> ```
>
> Ambas opciones generar un error que es enviado por el core.

## Bifurcaciones

```typescript
import {
  Actions,
  ConfForks,
  ErrorMs,
  Microservice,
  MsManager
} from "@coppel/microservices";

@MsManager.define({
  App: "NombreApp",
  Name: "NombreWorker",
  Version: "v1",
  Broker: ["127.0.0.1:9092"],
  Debug: true
})
class MiWorker extends Microservice {
  /**
   * Metodo de smoketest
   */
  public smoketest(): boolean | Promise<boolean> {
    // Retornar la promesa
    return new Promise((rr: (r: boolean) => void, ff: (r: boolean) => void) => {
      rr(true);
    });
  }

  /**
   *  Errores que puede tener el servicio.
   */
  @MsManager.Errors()
  public errores(): ErrorMs {
    return {
      "-12": "Error definido por el usuario"
    };
  }

  @MsManager.Fork()
  public configFork(): ConfForks {
    return {
      bif: {
        App: "appcoppel",
        Name: "prueba2",
        Version: "v1"
      },
      demo: {
        App: "appcoppel",
        Name: "simple",
        Version: "v1"
      }
    };
  }

  public initData(req: any, resp: any): any {
    return 10;
  }

  @MsManager.Listener([
    { action: Actions.DEFAULT, fork: "bif" },
    { action: Actions.CREATE, fork: "demo", fnc: "initData" } // Sin datos, se para data tal como llega
  ])
  public metodoList(@MsManager.ctx("request") data: any): any {
    return { todo: "ok1" };
  }
}
```
