MFE Integration

BaseMfePostgrestService

Classe astratta CRUD per service di dominio nei microfrontend — controparte MFE di BasePostgrestService, wrappa PostgrestMfeService e usa MFEHttpClient dalla shell host.

Cos'è

BaseMfePostgrestService<T, K> è la base class astratta per service di dominio CRUD in un microfrontend. Wrappa internamente un PostgrestMfeService, e espone i metodi canonici getAll, getById, create, update, delete + un helper protetto callRpc.

E la controparte MFE di BasePostgrestService: mantiene la stessa API logica ma adatta i tipi e il transport allo scenario microfrontend (HTTP via shell host, filtri come stringhe PostgREST grezze, niente cache integrata).

Signature

abstract class BaseMfePostgrestService<
  T extends Record<string, unknown>,
  K extends string | number = number,
> {
  constructor(
    http: MFEHttpClient,
    resource: string,
    primaryKey: keyof T & string,
    entityName?: string,
    logger?: ILogger,
  )

  getAll(query?: PostgrestQuery): Promise<{ data: T[]; totalRecords: number }>
  getById(id: K): Promise<T>
  create(data: Partial<T>): Promise<T>
  update(id: K, data: Partial<T>): Promise<T>
  delete(id: K): Promise<void>

  protected callRpc<R>(functionName: string, params: Record<string, unknown>): Promise<R>
}

Type parameters

ParametroVincoloDefaultDescrizione
Textends Record<string, unknown>Tipo dell'entità (es. Cliente, Fattura)
Kextends string | numbernumberTipo della chiave primaria

Costruttore

ParametroTipoDefaultDescrizione
httpMFEHttpClientOttenuto da useMfeContext().http
resourcestringNome risorsa PostgREST (tabella o vista, senza /)
primaryKeykeyof T & stringNome della colonna chiave primaria
entityNamestring'Record'Nome user-facing per messaggi di errore (es. 'Cliente')
loggerILoggerConsoleLoggerLogger per warning e errori

API

MetodoComportamento
getAll(query?)GET /resource?... con Prefer: count=exact se limit definito. Ritorna { data, totalRecords }
getById(id)GET /resource?{pk}=eq.{id} con Accept: application/vnd.pgrst.object+json. Errore "${entityName} non trovato: ${id}" se 0 risultati
create(data)POST /resource con Prefer: return=representation. Ritorna il record creato
update(id, data)PATCH /resource?{pk}=eq.{id} con Prefer: return=representation
delete(id)DELETE /resource?{pk}=eq.{id}
callRpc(name, params)(protected) POST /rpc/{name} — usabile solo dalle sottoclassi

Differenze rispetto a BasePostgrestService

AspettoBasePostgrestService (standalone)BaseMfePostgrestService (MFE)
HTTP clientAxios o Fetch interniMFEHttpClient dalla shell
AuthStrategia integrata (JWT/Cookie/ApiKey)Ereditata dalla shell
Cache5 strategie (IndexedDB, ecc.)Nessuna (responsabilità della shell)
getAll returnT[] semplice{ data, totalRecords }
FiltriFilterCriteria<T> type-safePostgrestQuery con filtri stringa grezzi
Schema PostgreSQLConfigurabile (Accept-Profile)Fissato dalla shell

Esempio: service di dominio

import type { MFEHttpClient } from '@pzeta/mfe-contracts'
import { BaseMfePostgrestService } from '@pzeta/postgrest/mfe'

interface Cliente {
  idanagrafica: number
  denominazione: string
  codicefiscale: string
  partitaiva: string
  codtipoanagrafica: 'CLI' | 'FOR' | 'DIP'
  datacreazione: string
}

export class ClientiMfeService extends BaseMfePostgrestService<Cliente, number> {
  constructor(http: MFEHttpClient) {
    super(http, 'anagrafica', 'idanagrafica', 'Cliente')
  }

  /** Metodo di dominio custom */
  async getRecenti(limite = 10): Promise<Cliente[]> {
    const { data } = await this.getAll({
      filters: { codtipoanagrafica: 'eq.CLI' },
      order: 'datacreazione.desc',
      limit: limite,
    })
    return data
  }

  /** RPC per metriche aggregate */
  async getMetricheAnno(idanagrafica: number, anno: number) {
    return this.callRpc<{ fatturato: number; numerOrdini: number }>(
      'get_metriche_cliente_anno',
      { p_idanagrafica: idanagrafica, p_anno: anno },
    )
  }
}

Esempio: uso nel componente Vue

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useMfeContext } from '@pzeta/mfe-contracts'
import { ClientiMfeService } from '@/services/ClientiMfeService'

const { http } = useMfeContext()
const service = new ClientiMfeService(http)

const clienti = ref<Cliente[]>([])
const totale = ref(0)
const loading = ref(false)

async function load() {
  loading.value = true
  try {
    const { data, totalRecords } = await service.getAll({
      order: 'denominazione.asc',
      limit: 25,
    })
    clienti.value = data
    totale.value = totalRecords
  } finally {
    loading.value = false
  }
}

onMounted(load)
</script>

Pattern di adozione

Mantieni una classe singola per tabella/vista PostgREST. Espone i metodi CRUD ereditati + i metodi di dominio specifici (getRecenti, getByCodice, RPC). I componenti Vue iniettano il service via inject/provide o lo istanziano una volta nel composable di pagina.

Tipi correlati