WCF RESTful service: cuocere per 5 minuti e servire

Spesso mi capita di lavorare con soluzioni architetturalmente articolate, che magari prevedono l'esposizione di servizi web in grado di permettere una certa interoperabilità o comunicazioni con sistemi esterni. Sempre più di frequente l'interoperabilità di cui parlo si applica anche all'interno della stessa piattaforma software, tra moduli divesi; tutte queste entità devono collaborare insieme con lo scopo prefissato dal flusso funzionale.

Quando l'obiettivo è creare un servizio web, la scelta che nella maggior parte delle volte si fa è quella di SOAP, cioè quella di un web service "standard", che si basa su un contratto che l'utilizzatore deve "accettare" prima di poter dialogare con l'entità che "offre" il servizio.

Naturalmente io non ho mai fatto eccezione a questa regola, se non quando mi sono dovuto confrontare con una soluzione che basava sulla comunicazioni tra servizi web, la maggior parte del proprio source code. Con il tempo il progetto ha iniziato a soffrire di quella che è detta essere la "sindrome da camicia stretta": un sacco di contratti, poca flessibilità e molto (ma molto) lavoro da fare per tenere tutti "in riga".

E' così che ho iniziato a guardare a soluzioni più "smart" e flessibili, in grado di garantirmi ottimi risultati, ottime prestazioni, utilizzo di standard multipiattaforma e una facilità di implementazione invidiabile. In una parola: REST.

Con la sigla REST (Representational State Transfer) si va a descrivere una soluzione di servizio che si basa su standard web estremamente diffusi (XML, ma sopratutto JSON, JavaScript Object Notation) e sfrutta efficacemente tutti i "verb" del protocollo HTTP ("GET", "POST", "PUT" e "DELETE") per eseguire le classiche operazioni di CRUD (Create, Read, Update e Delete) su un set di entità logiche.

Primo beneficio dell'utilizzo di REST, oltre al fatto di non dover rispettare nessun contratto predefinito, è l'override minimo che richiede per eseguire una invocazione. Secondo beneficio (non meno importante per uno sviluppatore) è la rapidità con cui è possibile implementarli attraverso la piattaforma WCF (Window Communication Foundation).

Non sono stato di parola: il titolo del mio post prometteva 5 minuti per ottenere un servizio REST pronto sul piatto...ma questa introduzione (spero utile, ma probabilmente superflua) ve ne avrà rubati già un paio. Quindi veniamo al sodo con un po' di codice...

Prima di tutto è necessario creare una soluzione di tipo "WCF Service Application" utilizzando il vostro Visual Studio. Cancellate tutti i file di sample che sono stati inseriti dal template, e il contenuto della "Web.config".

Definiamo un'interfaccia che servirà per contenere la defizione dei metodi (e si...ci sono anche qui) che dovremo esporre sul servizio REST. Per semplicità ho inserito solo due metodi: uno ("GetServerTime") che mi servirà unicamente come "tester" per verificare se il servizio risponde correttamente; il secondo metodo "FetchProducts" invece è quello che emette una lista di prodotti (sample, in questo caso) a fronte della sua invocazione, passando il nome della categoria di riferimento.

E' bene notare fin da subito che l'interfaccia del servizio deve essere marcata con l'attributo "[ServiceContract]", e ogni metodo con "[OperationContract]", al fine di permettere al motore di WCF di eseguire il "discovery" dei metodi. Inoltre ogni metodo riporta il "verb" (o "Method" come viene anche detto) su cui deve essere invocato affinchè lo stesso sia in grado di rispondere; come detto prima i metodi disponibili sono i soliti "GET", "POST", "PUT" e "DELETE" ed è consigliabile utilizzarli in maniera "semantica" ("GET" per le letture, "DELETE" per le cancellazioni, "POST" per gli inserimenti e "PUT" per le modifiche).

Altri parametri dell'attributo "[WebInvoke]" presente su ogni metodo, sono il formato per i dati di ingresso uscita (Xml o Json), il fatto che il corpo della risposta sia "Wrapped" ("inscatolato") oppure "Bare" ("ridotto") e, più importante degli altri, l' "UriTemplate" su cui il metodo risponderà.

Spendo due parole sull'UriTemplate perchè è estremamente importante. Un metodo, anche se è chiamato "GetServerTime", come in questo caso, risponderà esclusivamente alla chiamata "http://[server]/[servicename]/ServerTime" poichè il suo UriTemplate esegue la mappatura su tale stringa. Inoltre, per template parametrici tipo quello di "FetchProducts" ("Products/{categoryName}") è indispensabile che i parametri definiti nel metodo siano racchiusi tra parentesi graffe, siano denominati allo stesso modo che sulla firma del metodo stesso e, importantissimo, siano di tipo "stringa".

Dell'interfaccia e basta non ce ne facciamo nulla, quindi implementiamo il servizio: L'implementazione segue l'interfaccia, e i metodi devono semplicemente emettere un elemento del tipo richiesto: una data per "GetServerTime" e una lista di prodotti per "FetchProducts".

Ah...quasi dimenticavo di riportare il codice di Product, anche se la banalità della sua implementazione, quasi non merita nemmeno menzione. La classe è un semplice oggetto "DTO" (Data Transferable Object), detto anche "POCO" (Plain Old C-sharp Object); è composto solo da getter e setter, che ne garantiscono la facoltà di porter essere serializzato in XML o JSON facilmente. That's all folks! Il servizio è pronto per essere consumato. Ma vi starete chiedendo come accedere a questo benedetto (o maledetto) servizio, come hostarlo in IIS. Il post si è già dilungato parecchio, quindi vi lascio qualche giorno per far sedimentare le tante (forse troppe) informazioni, e vi anticipo che nel prossimo post illustrerò nei dettagli quella che è una delle caratteristiche più "fighe" che ho recentemente scoperto su IIS: il "service activation"...

Stay tuned!

Commenti

Post popolari in questo blog

Restore di un database SQL Server in un container Docker

Cancellazione fisica vs cancellazione logica dei dati

WCF RESTful service: esposizione del servizio