1. SVILUPPO DI SERVIZI REST PER
ANDROID
Ovvero tutto quello che abbiamo
imparato sviluppando servizi REST per
applicazioni Mobile
Luca Masini - @lmasini
GTUG Firenze
2. Agenda
• Obiettivi
• Architettura e infrastruttura
• REST e Livello 3
• Frameworks
• Multiplatform
• Security
• Versioning
• Caching
3. Obiettivi
• I servizi coprono:
– Aree informative
– Asset Digitali
– Ricerche su basi dati enterprise
– Servizi online
per un totale di circa 30 end-point
4. Obiettivi
• Realizzare servizi usabili da client
diversi...
come sistema operativo
come layout grafico
come risorse a disposizione
• Non si tratta quindi di API REST, ma di
servizi per un'applicazione specifica
5. Architettura e infrastruttura
• Internet è sia architettura che infrastruttura
• Il supporto tecnologico è diffuso (Java, .NET,
Python..) per la realizzazione di RESTful services
• Cloud non ha problemi di banda (ma i parametri
TCP/IP devono essere ottimizzati per il 3G)
• La scalabilità è assicurata (e dunque le
performance) da:
– Massimo disaccoppiamento (un link!)
– Caching (anche solo con 304 !!)
– Proxy
6. REST e livello 3
• Il RMM definisce quattro livelli di maturità a seconda di
quanto si usino HTTP, URI ed Hypermedia, partendo dallo
zero per i servizi che non usano alcuno di questi
(tipicamente SOAP !)
• Un servizio di “maturità 3” ha la caratteristica di:
– Indirizzare la risorsa tramite la URL
– Usare i verbi HTTP per indicare l'azione sulla risorsa
– Esporre una rappresentazione in grado di "guidare" lo
sviluppatore o la macchina a stati finiti verso
l'esplorazione del sistema (HATEOAS)
7. Frameworks Server
• La realizzazione di RESTful services è assicurata da
ogni tecnologia server-side:
– Windows Communication Foundation (WCF)
per .NET
– Il mondo Java ha una specifica proprio indirizzata
a REST, ovvero JAX-RS (ora in corso di definizione
la 2.1) e due implementazioni maggiori:
• RESTEasy di Jboss
• Jersey (la RI)
– Spring implementa REST tramite i RequestMapper
del framework MVC
8. Frameworks Client
• Chiamare i servizi REST con Apache
HTTP Client è come sviluppare Servlet
partendo dal socket !!
• Possiamo usare lo stesso idioma del
server con librerie come resteasy-
client-mobile
10. Multiplatform
• Realizzare servizi per piattaforme diverse
comporta la risoluzione di alcuni problemi:
– Diversificazione dell'informazione inviata al
client in base alle sue "capacità" (ad es.
risoluzione/dimensione schermo)
– Modalità diverse di rendering e
rappresentazione (ad es. i volantini)
– Wireframe diversi per versioni HD e non,
che però non giustificano nuovi end-point
11. Security
• Più che la sicurezza lato end-user,
comunque importante, il focus è stato
spostato sull'evitare che applicazioni
terze parti possano usare questi servizi
REST
• E' l'antitesi di quello che tutti fanno
oggi, ovvero rendere disponibili i dati
13. Security
// Facciamo un ESSENZIALE pool per le connessioni su questo socket !!!!
ConnPerRoute connPerRoute = new ConnPerRouteBean(12);
ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
ConnManagerParams.setMaxTotalConnections(params, 20);
// Set timeout
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
HttpConnectionParams.setSoTimeout(params, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
// Non seguo redirect
HttpClientParams.setRedirecting(params, false);
// Registro https con il nostro SSLSocketFactory
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("https", socketFactory, 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
DefaultHttpClient sClient = new DefaultHttpClient(conMgr, params);
// Finalmente faccio sta benedetta chiamata
HttpGet httpGet = new HttpGet("https://mobile.company.it/services/store/STOREID");
HttpResponse response = sClient.execute(httpGet);
HttpEntity httpEntity = response.getEntity();
14. Versioning
• L'evoluzione di un'app porta ad avere distribuiti
client di versioni diverse sui device degli utenti
• Le nuove caratteristiche portano a sviluppare
nuovi servizi
15. Versioning
• La criticità si ha quando servizi esistenti devono
tornare dati nuovi rimanendo compatibili !!!!!!
{
sigla: "NEG",
descrizione: "Negozio",
indirizzo: "Via dei Servizi REST",
cap: "50135",
comune: "Firenze",
provincia: "FI",
UrlDettaglio: “https://url.to.detail” // <== Nuovo attributo
}
16. Versioning
• La criticità si ha quando servizi esistenti devono
tornare dati nuovi rimanendo compatibili !!!!!!
{
sigla: "NEG",
descrizione: "Negozio",
indirizzo: "Via dei Servizi REST",
cap: "50135",
comune: "Firenze",
provincia: "FI",
UrlDettaglio: “https://url.to.detail” // <== Nuovo attributo
}
17. Versioning
• Il problema del versioning si può mitigare
tramite un corretto uso di JSON, delle API/User-
Agent e scrivendo fin da subito client che sono
molto "permissivi" a riguardo dei dati che
ricevono
@SourceServiceVersions(
@SourceServiceVersion(versionTag = VersionTag.HD, targetMethod = "methodForHD")
)
@Override
public List<Map<String, Object>> defaultMethod(String info) {}
@TargetServiceVersions(value = {VersionTag.HD})
public List<Map<String, Object>> methodForHD(String info) {}
18. Caching
• HTTP ed Internet hanno già implicito il concetto di caching, che
deve essere implementato però dai nostri servizi e dai nostri
client, rispettando i verbi HTTP e gli header di caching.
• Purtroppo le librerie HTTP delle piattaforme mobile mancano di
molti dei concetti che i browser implementano da decenni
• Vista l'alta latenza del 3G è importante pensare ad
implementare anche back-end caches dei nostri servizi
(memcached) o l'uso di back-end adatti al cloud (NoSQL)
20. Firenze GTUG
Google Technology User Group - Firenze
Site: http://sites.google.com/site/firenzegtug/
Blog: http://firenze-gtug.blogspot.it/
Group: firenze-gtug@googlegroups.com
...presto GDG
Google Developer Group