{"id":3335,"date":"2021-07-09T13:59:00","date_gmt":"2021-07-09T11:59:00","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=3335"},"modified":"2021-07-08T18:07:21","modified_gmt":"2021-07-08T16:07:21","slug":"caching-e-real-time-notifications-in-una-web-app-serverless-su-aws","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/","title":{"rendered":"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS"},"content":{"rendered":"\n

Le infrastrutture Serverless offrono enormi vantaggi rispetto alle infrastrutture server “classiche”. Basti pensare ad un’applicazione Web serverless di base basata su AWS sviluppata utilizzando AWS Lambda come livello di backend, DynamoDB on-demand (database), Cognito per l’autenticazione e S3-CloudFront per il frontend. Un’applicazione come questa \u00e8 perfettamente in grado di scalare automaticamente e in tempo reale, per accettare qualsiasi quantit\u00e0 di traffico. Rispetto ad una infrastruttura basata su EC2, avr\u00e0 un costo notevolemnte minore pur essendo molto pi\u00f9 semplice da implementare e mantenere. Adottare un paradigma Serverless sembra quindi una scelta quasi ovvia nella maggior parte delle situazioni: si andr\u00e0 a spendere meno per un’applicazione in grado di scalare meglio, che avr\u00e0 un maggiore isolamento, una migliore sicurezza e uno sforzo di manutenzione molto inferiore.<\/p>\n\n\n\n

\"Basic
Figura 1: Esempio di applicazione serverless di base<\/figcaption><\/figure><\/div>\n\n\n\n

Ad oggi sono stati creati diversi framework di sviluppo incentrati su AWS Lambda che rendono lo sviluppo di applicazioni serverless su AWS un gioco da ragazzi (ad es. Chalice per Python, Serverless-framework per diversi linguaggi). Inoltre, essendo dotati di tutte le necessarie integrazioni, \u00e8 abbastanza semplice creare pipeline CI\/CD utilizzando gli strumenti DevOps nativi di AWS (CodeBuild, CodeDeploy, CodePipeline) e integrare le applicazioni serverless con molti altri servizi AWS come SQS, SNS e Kinesis.<\/p>\n\n\n\n

Tuttavia, il passaggio a un’architettura serverless comporta nuovi problemi e soluzioni rispetto alle architetture pi\u00f9 tradizionali. La memorizzazione nella cache di risorse sia interne che esterne (es. query di database, risorse frontend ed API di terze parti) in particolare richiede strumenti e tecniche diverse da quelle utilizzate in un’architettura pi\u00f9 tradizionale, cos\u00ec come anche la gestione dei processi di lunga durata. <\/p>\n\n\n\n

Caching<\/strong><\/h2>\n\n\n\n

In un’applicazione tradizionale (es. Ruby on Rails o Django) la cache \u00e8 gestita con un deployment redis\/memcached locale oppure centralizzato che viene spesso utilizzato per tutto, dai componenti frontend alle query DB e alle risposte alle chiamate API esterne.<\/p>\n\n\n\n

In un ambiente serverless, la memorizzazione nella cache deve essere non solo molto veloce da accedere (pochi ms) e semplice da usare, ma anche senza necessit\u00e0 di connessioni persistenti e infinitamente scalabile. Questi requisiti rendono DynamoDB la scelta pi\u00f9 ovvia e solitamente la migliore: quando si configura una tabella come on-demand, infatti, la sua capacit\u00e0 di scrittura e lettura si ridimensiona automaticamente consentendo all’applicazione di rimanere reattiva anche in caso di improvviso aumento del traffico e il tempo di accesso alla tabella da Lambda rimane nell\u2019ordine dei millisecondi. Se \u00e8 necessario un tempo di accesso ancora pi\u00f9 basso \u00e8 possibile attivare Dynamo DAX Accelerator che pu\u00f2 abbassare ulteriormente la latenza di lettura passando cos\u00ec da millisecondi a microsecondi!<\/p>\n\n\n\n

\"Caching
Figura 2: memorizzazione nella cache in AWS: app basata su EC2 a sinistra, serverless a destra<\/figcaption><\/figure><\/div>\n\n\n\n

Jobs di lunga durata in un’applicazione Web serverless<\/h2>\n\n\n\n

In un’architettura tradizionale, un’applicazione Web di solito gestisce attivit\u00e0 con tempi di esecuzione prolungati generando thread e inviando notifiche tramite connessioni websocket aperte. Un’applicazione basata su Lambda, invece, normalmente gestisce un’attivit\u00e0 di lunga durata utilizzando AWS SQS o Kinesis come servizi di accodamento e container Fargate, oppure con Lambda autonome come worker. \u00c8 anche possibile eseguire attivit\u00e0 particolarmente complesse o con logica intricata avviando flussi di lavoro serverless con AWS StepFunctions.<\/p>\n\n\n\n

\"Long
Figura 3: Job a lunga esecuzione in un’applicazione web AWS: app basata su EC2 a sinistra, serverless a destra<\/figcaption><\/figure><\/div>\n\n\n\n

Infine, spesso \u00e8 utile inviare una notifica direttamente al browser client per aggiornare lo stato dei componenti del frontend in risposta a eventi come come stato di esecuzione delle attivit\u00e0 in esecuzione, notificare all’utente azioni eseguite da altri utenti (ad esempio nei giochi online), recapitare messaggi e sempre pi\u00f9 spesso notificare agli utenti i cambiamenti di stato di dispositivi IoT. <\/p>\n\n\n\n

Notifiche in tempo reale<\/h2>\n\n\n\n

Mentre nelle applicazioni classiche \u00e8 possibile utilizzare direttamente i websocket, anche tramite AWS ELB che supportano HTTP\/2, per le applicazioni serverless \u00e8 necessario sfruttare il supporto Websocket di AWS ApiGateway che \u00e8 anche supportato nativamente da diversi framework serverless, come Chalice. Quando una connessione WebSocket viene stabilita da un client, una lambda pu\u00f2 essere invocata dall’hook $connect<\/em>  di ApiGateway e sar\u00e0 in grado di registrare l’id di connessione a un database, solitamente DynamoDB. Quando un utente si disconnette, viene invocato $disconnect<\/em> e ci\u00f2 consente alla nostra applicazione di eliminare il record dalla tabella delle connessioni. Sviluppare una logica per inviare notifiche \u00e8 piuttosto semplice: quando un messaggio deve essere consegnato dal backend a un utente, l’ApiGateway @connections POST Api viene invocato utilizzando gli id delle connessioni websocket aperte dell’utente e ApiGateway si occupa di inoltrare il messaggio nel canale websocket aperto.<\/p>\n\n\n\n

\"Real
Figura 4: Notifiche Websocket in tempo reale in un’applicazione Web AWS: app basata su EC2 a sinistra, serverless a destra <\/figcaption><\/figure>\n\n\n\n

Un esempio del mondo reale<\/h2>\n\n\n\n

Sebbene queste tecniche siano particolarmente utili per le applicazioni ad alto traffico, anche le app a basso traffico possono trarre grandi vantaggi dalla loro implementazione, in particolare quelle che gestiscono flussi di lavoro complessi. <\/p>\n\n\n\n

La seguente architettura di esempio \u00e8 una versione notevolmente semplificata dell’architettura che abbiamo effettivamente realizzato per un’applicazione che consente ad un cliente di gestire dinamicamente i bucket S3 e gli utenti IAM che vi accedono.<\/p>\n\n\n\n

\"dynamically
Figura 5: Prima versione dell’infrastruttura applicativa di esempio<\/figcaption><\/figure><\/div>\n\n\n\n

L’applicazione consente ai project manager del cliente di creare facilmente bucket S3 protetti in account AWS dedicati, specifici per progetto, isolati e hardenizzati. Una volta creati i bucket, \u00e8 anche possibile generare utenti IAM gestiti per accedervi. Le credenziali dell’utente IAM possono quindi essere condivise in modo sicuro con terze parti per consentire loro di scaricare e\/o caricare file da S3 utilizzando sistemi legacy on-premise, sfruttando le API di S3 o SFTP (AWS Transfer for SFTP). Utenti e Bucket possono essere facilmente aggiunti e rimossi da ciascun progetto e le autorizzazioni utente possono essere gestite tramite una semplice interfaccia utente.<\/p>\n\n\n\n

Per semplificare lo sviluppo del backend e allo stesso tempo rendere l’applicazione pi\u00f9 resiliente, abbiamo deciso di non configurare alcun database e utilizzare semplicemente il backend per creare, aggiornare e modificare dei modelli di Cloudformation che descrivono l\u2019intera infrastruttura AWS. In questo modo viene rafforzata la consistenza dell\u2019applicazione: ogni azione eseguita viene automaticamente registrata e, in caso di errore durante la creazione di una risorsa, i rollback vengono eseguiti automaticamente direttamente dal servizio Cloudformation.<\/p>\n\n\n\n

Tuttavia questo approccio presenta due svantaggi principali, uno per le operazioni LIST\/GET e uno per le operazioni CREATE\/UPDATE. <\/p>\n\n\n\n

Infatti, ogni volta che un utente finale elenca le risorse esistenti, il backend deve recuperare tutti i modelli di CloudFormation, analizzarli per elencare le risorse e infine restituire la risposta. Questo flusso deve essere eseguito almeno su un modello ogni volta che un utente esegue un’operazione LIST o GET. Per account con dozzine di bucket e utenti ci\u00f2 pu\u00f2 richiedere diversi secondi, rendendo l’esperienza dell’utente molto scadente e potenzialmente, in alcuni casi estremi, pu\u00f2 portare al superamento del limite di risposta di ApiGateway (30 secondi).<\/p>\n\n\n\n

Il secondo problema riguarda le operazioni di aggiornamento e si manifesta quando sono connessi pi\u00f9 clienti: se un gestore aggiorna un bucket o un utente, tutti gli altri gestori non potranno modificarlo fino al termine dell’esecuzione di Cloudformation, che in questo caso d’uso richiede solo pochi secondi. Tuttavia, gli altri utenti connessi non hanno modo di sapere quando un utente viene aggiornato e potrebbero tentare di modificarlo causando errori imprevisti che, sebbene innocui, rendono l’esperienza dell’utente poco fluida.<\/p>\n\n\n\n

Oltre a questi problemi c’\u00e8 anche un’ulteriore potenziale inconveniente: poich\u00e9 l’infrastruttura descritta \u00e8 “GET heavy” verso le API di CloudFormation, se un numero sufficientemente grande di gestori accede, il rate limit dell’API di CloudFormation potrebbe potenzialmente essere superato con conseguenti ulteriori rallentamenti (gli SDK AWS implementano l\u2019esponential backoff).<\/p>\n\n\n\n

Per risolvere tutti questi problemi, dopo l’MVP iniziale, abbiamo applicato il design pattern sopra descritto per rendere applicazione pronta per essere messa in produzione: abbiamo utilizzato DynamoDB per memorizzare nella cache lo stato di CloudFormation e abbiamo utilizzato l’integrazione di CloudFormation con SNS per aggiornare lo stato in tempo reale tramite connessioni Websocket (gestite da Api Gateway) verso i client degli utenti e allo stesso tempo per aggiornare la cache su dynamoDB con l’ultimo stato di Cloudformation, in modo che lo stato nel DB di cache rispecchi sempre lo stato di Cloudformation.<\/p>\n\n\n\n

\"Ready
Figura 6: versione finale dell’infrastruttura applicativa di esempio<\/figcaption><\/figure><\/div>\n\n\n\n

Questi accorgimenti hanno prodotto enormi miglioramenti nei tempi di risposta delle APIs del backend, che per le richieste GET\/LIST sono scesi costantemente al di sotto dei 200 ms. Inoltre, il tempo di attesa degli utenti dopo il lancio di un aggiornamento di CloudFormation risulta notevolmente diminuito e lo stato delle risorse \u00e8 coerente su tutti i client connessi.<\/p>\n\n\n\n

Il cliente \u00e8 stato pi\u00f9 che soddisfatto del risultato finale e un cliente felice \u00e8 sempre la migliore conferma di un lavoro ingegneristico ben fatto!<\/p>\n\n\n\n

Se hai domande sui modelli di progettazione per DynamoDB o su qualsiasi altro argomento riguardante (o non riguardante) questo articolo, non esitare a contattarci! Non vediamo l’ora di discuterne \ud83d\ude42<\/p>\n\n\n\n

Ci vediamo qui, su #Proud2beCloud<\/strong> tra 14 giorni per un nuovo articolo!<\/p>\n","protected":false},"excerpt":{"rendered":"

Le infrastrutture Serverless offrono enormi vantaggi rispetto alle infrastrutture server “classiche”. Basti pensare ad un’applicazione Web serverless di base basata […]<\/p>\n","protected":false},"author":9,"featured_media":3347,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[481],"tags":[263,522,524,267],"yoast_head":"\nCaching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS - Proud2beCloud Blog<\/title>\n<meta name=\"description\" content=\"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Gestire caching e notifiche real-time in una web app Serverless basata su AWS\" \/>\n<meta property=\"og:description\" content=\"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/\" \/>\n<meta property=\"og:site_name\" content=\"Proud2beCloud Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-07-09T11:59:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-07-08T16:07:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2021\/07\/CopertineBlog_7-07-21-social-ita.png\" \/>\n\t<meta property=\"og:image:width\" content=\"5001\" \/>\n\t<meta property=\"og:image:height\" content=\"2618\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Matteo Moroni\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Gestire caching e notifiche real-time in una web app Serverless basata su AWS\" \/>\n<meta name=\"twitter:description\" content=\"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2021\/07\/CopertineBlog_7-07-21-social-ita.png\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matteo Moroni\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/\",\"url\":\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/\",\"name\":\"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS - Proud2beCloud Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\"},\"datePublished\":\"2021-07-09T11:59:00+00:00\",\"dateModified\":\"2021-07-08T16:07:21+00:00\",\"author\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/0b3e69eb2dcb125d58476b906ec1c7bc\"},\"description\":\"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.besharp.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\",\"url\":\"https:\/\/blog.besharp.it\/it\/\",\"name\":\"Proud2beCloud Blog\",\"description\":\"il blog di beSharp\",\"alternateName\":\"Proud2beCloud Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.besharp.it\/it\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/0b3e69eb2dcb125d58476b906ec1c7bc\",\"name\":\"Matteo Moroni\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/acad790b9bb4c6d62e076ecdc1debb35?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/acad790b9bb4c6d62e076ecdc1debb35?s=96&d=mm&r=g\",\"caption\":\"Matteo Moroni\"},\"description\":\"DevOps e Solution Architect di beSharp, mi occupo di sviluppare soluzioni Saas, Data Analysis, HPC e di progettare architetture non convenzionali a complessit\u00e0 divergente. Appassionato di informatica e fisica, da sempre lavoro nella prima e ho un PhD nella seconda. Parlare di tutto ci\u00f2 che \u00e8 tecnico e nerd mi rende felice!\",\"url\":\"https:\/\/blog.besharp.it\/it\/author\/matteo-moroni\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS - Proud2beCloud Blog","description":"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/","og_locale":"it_IT","og_type":"article","og_title":"Gestire caching e notifiche real-time in una web app Serverless basata su AWS","og_description":"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.","og_url":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/","og_site_name":"Proud2beCloud Blog","article_published_time":"2021-07-09T11:59:00+00:00","article_modified_time":"2021-07-08T16:07:21+00:00","og_image":[{"width":5001,"height":2618,"url":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2021\/07\/CopertineBlog_7-07-21-social-ita.png","type":"image\/png"}],"author":"Matteo Moroni","twitter_card":"summary_large_image","twitter_title":"Gestire caching e notifiche real-time in una web app Serverless basata su AWS","twitter_description":"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.","twitter_image":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2021\/07\/CopertineBlog_7-07-21-social-ita.png","twitter_misc":{"Scritto da":"Matteo Moroni","Tempo di lettura stimato":"8 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/","url":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/","name":"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS - Proud2beCloud Blog","isPartOf":{"@id":"https:\/\/blog.besharp.it\/it\/#website"},"datePublished":"2021-07-09T11:59:00+00:00","dateModified":"2021-07-08T16:07:21+00:00","author":{"@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/0b3e69eb2dcb125d58476b906ec1c7bc"},"description":"In questo articolo vediamo come gestire caching, notifiche real time e processi long-running in una web app serverless su AWS.","breadcrumb":{"@id":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.besharp.it\/it\/caching-e-real-time-notifications-in-una-web-app-serverless-su-aws\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.besharp.it\/it\/"},{"@type":"ListItem","position":2,"name":"Caching e long-jobs con notifiche in tempo reale in una Web App Serverless basata su AWS"}]},{"@type":"WebSite","@id":"https:\/\/blog.besharp.it\/it\/#website","url":"https:\/\/blog.besharp.it\/it\/","name":"Proud2beCloud Blog","description":"il blog di beSharp","alternateName":"Proud2beCloud Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.besharp.it\/it\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/0b3e69eb2dcb125d58476b906ec1c7bc","name":"Matteo Moroni","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/acad790b9bb4c6d62e076ecdc1debb35?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/acad790b9bb4c6d62e076ecdc1debb35?s=96&d=mm&r=g","caption":"Matteo Moroni"},"description":"DevOps e Solution Architect di beSharp, mi occupo di sviluppare soluzioni Saas, Data Analysis, HPC e di progettare architetture non convenzionali a complessit\u00e0 divergente. Appassionato di informatica e fisica, da sempre lavoro nella prima e ho un PhD nella seconda. Parlare di tutto ci\u00f2 che \u00e8 tecnico e nerd mi rende felice!","url":"https:\/\/blog.besharp.it\/it\/author\/matteo-moroni\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/3335"}],"collection":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/comments?post=3335"}],"version-history":[{"count":0,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/3335\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media\/3347"}],"wp:attachment":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media?parent=3335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/categories?post=3335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/tags?post=3335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}