Passa al contenuto principale
Versione: 2025.002.000

Basic Notions

TS Enterprise WebApi è un ecosistema di webservice che segue i principi architetturali REST, e si fonda su poche semplici regole generali.

Di seguito è riportata una panoramica dei principi fondamentali dell’architettura di tipo REST, insieme ad alcuni dettagli su come questi principi sono declinati in Enterprise.
Si rimanda al corso di formazione tecnico "ENT355 - TS Enterprise - DOMAIN MODEL E SVILUPPO WEB API" inserito all’interno del calendario education per ulteriori approfondimenti.

Definizione di risorse sotto forma di URL

Basato su protocollo HTTP.

In TSE WebAPI è possibile interrogare il servizio attraverso semplici richieste HTTP, utilizzando client basati su qualsiasi tecnologia: web browser, client C#, java, python, javascript, sistemi operativi windows o linux.

Ogni URL definisce univocamente l’accesso ad una risorsa dati.

Sono gli URL che identificano su che tipo di dato si sta operando. Se non diversamente specificato in fase di configurazione, le WepAPI di TSE rispondono all'indirizzo locale:

http://localhost:9080/api/v1/{ambiente}/{modulo}/{risorsa}

Lato consumer le api sono messe a disposizione attraverso i servizi di routing dell'APIGateway e faremo quindi riferimento, per ogni risorsa, all'URL:

https://webapi_base_url/v1/{ambiente}/{modulo}/{risorsa}

Ogni risorsa è organizzata per modulo. L'esplicita indicazione del modulo permette di instradare la richiesta verso il corretto servizio di riferimento.

Ad esempio, assumendo il servizio web api in ascolto all’url “root” http://localhost/api/v1/scope/, in cui "scope" è il nome dell’ambiente di lavoro (si veda il paragrafo successivo), le differenti funzionalità esposte dal servizio sono esposte come URL basati su questa root.

Di seguito alcuni esempi:

  • http://localhost/api/v1/scope/MG/documento/ url risorsa per TUTTE le possibili operazioni sui documenti
  • http://localhost/api/v1/scope/CO/CompanyCO/ url risorsa per TUTTE le possibili operazioni sulle aziende
  • http://localhost/api/v1/scope/CO/GeneralMasterDataCO/ url risorsa per TUTTE le possibili operazioni sulle anagrafiche generali

Tutte le entità di tipo root sono esponibili come risorse nel servizio WebAPI semplicemente compilando i relativi metadati per Controller, Manager e DTO (si veda il dettaglio in seguito).

Naming conventions

Per convenzione, ogni risorsa assume di default il nome dell’entità stessa, in inglese, a meno che in fase di sviluppo non si decida diversamente; ad esempio, nel caso dell’entità “DocumentoTestataMG”, in fase di sviluppo si è deciso di esporre questa risorsa non utilizzando il valore di default “DocumentoTestataMG” ma utilizzando il valore “documento”.

Ambienti come risorsa

Parlando di risorse, la prima e più importante è l’ambiente applicativo di lavoro, ovvero la parte di URL alla destra della “root” http://localhost/api/v1/, ad esempio: “scope” in http://localhost/api/v1/scope/.

L’ambiente applicativo identifica un’area di lavoro associata ad un database: le risorse di ogni ambiente, ad esempio “gammanext/documenti” e “servicenext/documenti” hanno quindi tutte la stessa struttura ma rappresentano dati diversi.

Autenticazione

Si veda la sezione AUTENTICAZIONE per informazioni su come accedere agli ambienti disponibili.

Rispetto della semantica e dei comandi HTTP

Definita una risorsa sotto forma di URL, le operazioni possibili su quella risorsa sono legate all’URL della risorsa stessa e ai metodi HTTP utilizzata dal chiamante.

Ad esempio:

  • GET: recupera la risorsa, ovvero il DTO configurato con chiave specificata in URL
  • PUT: modifica la risorsa con chiave specificata in URL, nel body sarà presente lo stesso DTO ritornato dalla GET, con le opportune proprietà modificate
  • DELETE: elimina la risorsa con chiave specificata in URL
  • POST: crea un nuovo elemento della risorsa e ritorna il relativo DTO
  • PATCH: modifica solo una specifica proprietà del DTO, non c'è quindi la necessità di inoltrare tutto il DTO nel body ma solo la/le proprietà da aggiornare. Nel caso si volesse modificare la/le proprietà di un elemento di una collezione relazionata internamente, è necessario specificare anche le chiavi dell'entità relazionata, oltre le proprietà che si intende modificare.

Quando si parla di “recupera”, “modifica”, “elimina” e “crea” si intendono le relative operazioni implementate dallo specifico Biz che gestisce l’aggregato. Ogni operazione offerta da Enterprise WebAPI deve essere considerata come “esposizione verso client esterni tramite servizi REST” di operazioni di business, a meno di casi particolari.

NOTE: si noti la differente semantica della operazione POST, che non richiede di specificare l’id nell’URL, a differenza delle altre operazioni GET, PUT e DELETE. Di fatto, la POST viene utilizzata per tutte le operazioni che non lavorano direttamente su una risorsa esistente, come:

  • Search: ricerca libera (per valore testuale o filtro specifico) sulla risorsa
  • Validate: validazione di una risorsa (ovvero il DTO rappresentate l’entità aggregato) che può essere esistente o non ancora creata
  • ValidateProperties: validazione di una o più proprietà di una risorsa, esistente o meno
  • Other: altre operazioni, di qualsiasi tipo, implementate per casi specifici (es: Approva o Rifiuta RDA)

Anche queste operazioni di fatto richiamano le relative operazioni presenti nel Biz standard, ovvero le operazioni di Search e Validate, o create dal programmatore (nel caso “Other”).

warning

I metodi HTTP HEAD, CONNECT, OPTIONS, TRACE non sono utilizzati.

Risorse autodescrittive

Come accennato in precedenza, ogni operazione di lettura/scrittura su una risorsa opera su un DTO, ovvero un Data Transfer Object specificatamente definito per disaccoppiare la rappresentazione della risorsa esposta ai client esterni dall’entità definita a livello di biz.

Il formato di serializzazione del DTO da utilizzare come interscambio può essere definito dal client che interroga il servizio aggiungendo alla richiesta l’header HTTP “Accept”, e sono supportati due valori:

  • application/json: serializzazione JSON; è il valore di default utilizzato in caso che l’header “Accept” non sia specificato dal chiamante
  • application/xml: serializzazione XML

La risposta del servizio contiene, nel suo header “Content-Type” il formato di serializzazione, ovvero:

  • application/json: serializzazione JSON; è il valore di default utilizzato in caso che l’header “Accept” non sia stato specificato dal chiamante
  • application/xml: serializzazione XML
  • text/html: in caso di messaggi di errore, e nelle operazioni che ritornano contenuto testuale, ad esempio “Validate” e “ValidateProperties”
encoding

Viene ritornato anche l’encoding utilizzato (in genere utf-8), ad esempio:

REQUEST  => Accept: application/json
RESPONSE => Content-Type: application/json; charset: utf-8

Localizzazione

Anche il supporto multilingua è gestito tramite header HTTP; in particolare, specificando l’header “Accept-Language” con un valore specifico in standard RFC 4646, la sessione applicativa viene inizializzata utilizzando le informazioni di globalizzazione specificate.

REQUEST  => Accept-Language: en-US
RESPONSE => Content-Language: en-US
Language

Di default, ovvero in caso di “Accept-Language” non specificato, la sessione viene inizializzata con le informazioni di globalizzazione della lingua italiana “it-IT”.

Protocollo stateless

In rispetto del protocollo HTTP, ogni richiesta proveniente dai client è processata in modo completamente stateless, ovvero una qualsiasi richiesta non ha relazione con le precedenti richieste effettuate dallo stesso chiamante. Una singola richiesta deve quindi contenere TUTTE le informazioni necessarie per poter eseguire l’operazione desiderata, a partire dalle informazioni di autenticazione e di creazione della sessione utente.

Nel caso di una richiesta GET occorre specificare:

  • Tipo di autenticazione: obbligatorio
  • Credenziali: obbligatorie, dipendenti dal sistema di autenticazione usato
  • Header “Authorization-Scope”: obbligatorio, header di accesso all’ambiente richiesto
  • Query parameter “user”: opzionale, in caso si volesse eseguire l’operazione “impersonando” un utente applicativo diverso da quello mappato a livello di configurazione utente del servizio; la specifica del parametro segue le specifiche standard, ad esempio ?user=guest
  • Query parameter “company”: obbligatoria sulle risorse dipendenti dall'azienda; la specifica del parametro segue le specifiche standard, ad esempio ?company=1dove '1' è l'azienda di lavoro.

Sicurezza ed idempotenza

Si definisce un metodo come SAFE – sicuro - quando la relativa richiesta non altera in alcun modo lo stato della risorsa stessa e di eventuali risorse collegale: si parla quindi più genericamente di metodi SAFE in quanto non alterano lo stato del server.

I metodi GET sono SAFE, possono quindi essere chiamati innumerevoli volte senza preoccuparsi di “side effects”, mentre i metodi PUT E DELETE non sono SAFE per definizione: ogni PUT modifica la relativa risorsa (a meno di passare sempre la stessa rappresentazione, ma anche in questo caso potrebbero essere diversi alcuni campi autogenerati), mentre la DELETE elimina la risorsa rendendola non più disponibile.

Il metodo POST ha un comportamento dipendente dal tipo di operazione implementata; il metodo POST non è SAFE relativamente all’operazione “Create”, mentre i metodi POST relativi alle operazioni “Search”, ”Validate” e ”ValidateProperties” sono SAFE. Eventuali operazioni “custom” possono essere SAFE o meno, in funzione della operazione implementata; si veda il paragrafo relativo alle operazioni POST per ulteriori dettagli.

Si definisce un metodo come IDEMPOTENT – idempotente – se non vi è alcuna differenza nello stato del server tra l’esecuzione di una richiesta singola o N richieste multiple della stessa identica richiesta.

Il metodo GET è quindi idempotente perché, al netto di processi esterni di modifica del dato in lettura, lo stato del server rimane invariato indipendentemente dal numero di richieste effettuate (non si considerano logging e processi interni come contatori o altro). I metodi PUT e DELETE sono anch’essi idempotenti perché lo stato del server viene alterato solo alla prima richiesta di eliminazione o modifica mentre le successive non modificano (o non dovrebbero modificare) lo stato del server.

Il metodo POST non è genericamente considerato idempotente: non lo è per l’operazione “Create” (ad ogni richiesta viene creata una risorsa distinta), mentre lo è per le operazioni “Search”, ”Validate” e ”ValidateProperties”.

Schema generale

Per ogni risorsa esposta dal servizio, il framework mette a disposizione una serie di operazioni per il CRUD, la ricerca, la validazione e le lookup sui dati.

L’URL di base di tutte chiamate è il seguente: http|https://{server}[:{porta}]/api/{versione}/{ambiente}

  • {versione}: v1
  • {ambiente}: sigla corrispondente ad un ambiente configurato (vedi CONFIGURAZIONE)
PORTA

Il parametro porta è opzionale; se non specificata, di default viene utilizzata la porta 80 per le richieste HTTP o la porta 443 per richieste HTTPS.

Utente applicativo e azienda di lavoro

In ogni richiesta al servizio WebApi è possibile specificare i parametri

  • user: nome dell’utente applicativo
  • company: azienda di lavoro, parametro obbligatorio nelle chiamate funzionali

Questi parametri vanno aggiunti all’URL con sintassi standard, in questo modo:

GET: http://{server}:{porta}/api/v1/{ambiente}/{modulo}/{risorsa}/{id}?user=TeamSa&company=1

Se non specificati, i valori utilizzati saranno quelli specificati in fase di configurazione dell’utente utilizzato per l’autenticazione al servizio.