{"id":284,"date":"2018-09-25T12:48:07","date_gmt":"2018-09-25T10:48:07","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=284"},"modified":"2021-03-17T12:13:22","modified_gmt":"2021-03-17T11:13:22","slug":"go-serverless-pt2","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/","title":{"rendered":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing"},"content":{"rendered":"

Leggi la prima parte<\/a> | Leggi la terza parte<\/a><\/p>\n

Con la sempre maggiore diffusione dello sviluppo Serverless, \u00e8 di fondamentale importanza comprendere come sfruttarne tutti i vantaggi per poter realizzare applicazioni scalabili<\/strong> e resilienti<\/strong>.<\/p>\n

Questa \u00e8 la seconda parte della serie di 3 articoli (qui<\/a> trovate la prima parte) su come costruire una piattaforma di file sharing completamente serverless<\/strong>. In questo articolo <\/span>andremo a realizzare<\/span> l\u2019infrastruttura, approfondendo gli aspetti fondamentali per una corretta ed efficace implementazione.<\/span><\/p>\n

Come anticipato nell\u2019<\/span>articolo <\/span><\/a>precedente, oltre all\u2019infrastruttura dell\u2019applicazione andremo anche a realizzare le pipeline di Continuous Integration e Continuous Delivery<\/strong>. <\/span><\/p>\n

Cominciamo con il primo dei due punti.<\/span><\/p>\n

Non tratteremo qui del codice applicativo e degli argomenti correlati allo sviluppo, che saranno descritti in modo approfondito nel prossimo articolo. Per testare l\u2019infrastruttura impiegheremo delle semplici pagine statiche e una funzione lambda di test.<\/span><\/p>\n

Iniziamo con l\u2019analisi della soluzione presentata nella prima parte della serie.<\/span><\/p>\n

\"\"L\u2019applicazione \u00e8 composta da un front-end<\/strong> e un back-end<\/strong><\/p>\n

Il front-end \u00e8 una single page application di cui effettueremo il deploy su S3 e che sar\u00e0 servita mediante CloudFront<\/strong>. Il back-end invece \u00e8 una API REST realizzata con API Gateway<\/strong> e Lambda<\/strong>.<\/span><\/p>\n

Per realizzare l\u2019infrastruttura occorre effettuare il provisioning e la configurazione delle seguenti risorse AWS:<\/span><\/p>\n

front-end<\/strong><\/h3>\n
    \n
  1. Un bucket S3 privato per il front-end<\/span><\/li>\n
  2. Una distribuzione di CloudFront con il permesso di accedere al bucket S3<\/span><\/li>\n<\/ol>\n

    back-end<\/strong><\/h3>\n
      \n
    1. Una funzione lambda per testare l\u2019integrazione<\/span><\/li>\n
    2. Una Cognito User Pool<\/span><\/li>\n
    3. Un Bucket S3 privato per gli upload degli utenti<\/span><\/li>\n
    4. Una tabella DynamoDB<\/span><\/li>\n
    5. Una API di API Gateway<\/span><\/li>\n<\/ol>\n

      PREPARAZIONE DEL FRONT-END<\/strong><\/h3>\n

      Per prima cosa andiamo a creare un bucket S3 dove caricare l\u2019applicazione javascript e html per il front-end.<\/span><\/p>\n

      Lo stesso bucket sar\u00e0 la sorgente per la distribuzione di CloudFront.<\/span><\/p>\n

      Il bucket pu\u00f2 essere privato, configureremo la distribuzione in modo da consentire a CloudFront l\u2019accesso al bucket S3.<\/span><\/p>\n

      \"\"<\/p>\n

      \"\"<\/p>\n

      Dopo \u00e8 possibile caricare un semplice file di prova, che useremo per verificare il corretto funzionamento del front-end.<\/span><\/p>\n

       <\/p>\n

      <html><\/span>\r\n\u00a0 \u00a0 \u00a0 <head><\/span>\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <title><\/span>Esempio<\/span><\/title><\/span>\r\n\u00a0 \u00a0 \u00a0 <\/head><\/span>\r\n\r\n\u00a0 \u00a0 \u00a0 <body><\/span>\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<h1><\/span>It Works<\/span><\/h1><\/span>\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<hr\/><\/span>\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<p><\/span>This is a simple test page<\/span><\/p><\/span>\r\n\u00a0 \u00a0 \u00a0 <\/body><\/span>\r\n<\/html><\/span><\/pre>\n

       <\/p>\n

      Salviamo questo file come \u201cindex.html<\/strong>\u201d e carichiamolo nel bucket appena creato.<\/span><\/p>\n

      \"\"<\/p>\n

      \"\"<\/p>\n

      Una volta ultimate le operazioni per la creazione del bucket S3 occorre creare una distribuzione CloudFront<\/strong> che lo utilizzi come origine. Questo per distribuire il file che abbiamo caricato, che non \u00e8 al momento accessibile.<\/span><\/p>\n

      Nella configurazione della distribuzione \u00e8 importante abilitare l\u2019opzione \u201cRestrict Bucket Access<\/strong>\u201d per mantenere il bucket S3 privato. <\/span><\/p>\n

      Al fine di consentire al servizio CloudFront di accedere al bucket in lettura bisogna provvedere ad attivare e configurare l\u2019opzione \u00a0\u201cOrigin Access Identity<\/strong>\u201d; \u00e8 possibile delegare al wizard la creazione di una Access Identity e l\u2019aggiornamento della Bucket Policy.<\/span><\/p>\n

      \"\"<\/p>\n

      Per quanto riguarda le impostazioni del comportamento di caching<\/strong> attiviamo il redirect di http su https e abilitiamo la compressione automatica dei contenuti serviti per migliorare le performance.<\/span><\/p>\n

      \"\"<\/p>\n

      Non bisogna dimenticare di indicare quale file servire di default se non indicato, ed impostarlo ad index.html<\/span><\/p>\n

      \"\"<\/p>\n

      Il processo di creazione della distribuzione pu\u00f2 richiedere diversi minuti.<\/span>
      \n<\/span>In alcuni casi, anche dopo l\u2019attivazione della distribuzione potrebbe essere visualizzato un errore di accesso, tuttavia si tratta di una situazione transitoria dovuta ai tempi di propagazione DNS, e si risolve autonomamente entro qualche minuto. [Pu\u00f2 richiedere fino ad un ora NDR]<\/span><\/p>\n

      Quando la distribuzione sar\u00e0 pronta \u00e8 possibile ottenere l\u2019url pubblico e testare il deploy del front-end navigando a quell\u2019indirizzo.<\/span><\/p>\n

      Dovrebbe essere visualizzata la pagina di esempio che abbiamo caricato nei passaggi precedenti.<\/span><\/p>\n

      \"\"<\/p>\n

      Il front-end \u00e8 quindi pronto.<\/strong> Il contenuto del bucket viene servito in modo efficiente e cost effective attraverso la CDN; per aggiornare l\u2019applicazione basta caricarla su S3. <\/span><\/p>\n

      Attenzione! se si modificano file gi\u00e0 presenti occorre invalidare la cache della distribuzione per vedere gli aggiornamenti.<\/span><\/em><\/p>\n

      PREPARAZIONE DEL BACK-END<\/strong><\/h3>\n

      Passiamo ora alla realizzazione dell\u2019infrastruttura del back-end del nostro sistema di file sharing.<\/span><\/p>\n

      Come prima cosa possiamo creare una funzione lambda<\/strong> che utilizzeremo ai fini di test.<\/span><\/p>\n

      Come abbiamo gi\u00e0 detto, non ci occuperemo adesso dell\u2019applicazione vera e propria, ma solo di costruire tutte le parti dell\u2019infrastruttura. Questa funzione non far\u00e0 altro che restituire uno stato di successo ed un messaggio.<\/span><\/p>\n

      Procediamo quindi con la creazione della funzione impostando Python come Runtime e assegnando un ruolo con permessi di base.<\/span><\/p>\n

      \"\"Ecco un esempio per restituire sempre un messaggio:<\/span><\/p>\n

       <\/p>\n

      def<\/b> lambda_handler<\/b>(event, context):<\/span>\r\n \u00a0\u00a0\u00a0<\/span>\r\n \u00a0\u00a0\u00a0response = {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"statusCode\"<\/span>: <\/span>200<\/b>,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"body\"<\/span>: <\/span>'Hello from Lambda!'<\/span>\r\n \u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0<\/span>\r\n \u00a0\u00a0\u00a0<\/span>return<\/b> response<\/span><\/pre>\n

       <\/p>\n

      Testiamo la funzione, se tutto \u00e8 stato impostato correttamente il test dovrebbe riuscire con un output simile a quello seguente:<\/span><\/p>\n

      {<\/span>
      \n<\/span> \u00a0<\/span>“statusCode”<\/span>: <\/span>200<\/b>,<\/span>
      \n<\/span> \u00a0<\/span>“body”<\/span>: <\/span>“Hello from Lambda!”<\/span>
      \n<\/span>}<\/span><\/p>\n

      Una volta pronta la funzione possiamo effettuare il provisioning delle altre risorse<\/strong>.<\/span><\/p>\n

      All\u2019applicazione occorrer\u00e0 un ulteriore bucket S3 per gli upload dei file degli utenti. Anche in questo caso si tratter\u00e0 di un bucket privato. Provvediamo quindi alla sua creazione nello stesso modo utilizzato per il front-end, e prendiamo nota del nome del bucket, ci servir\u00e0 per la configurazione dell\u2019applicazione.<\/span><\/p>\n

      Servir\u00e0 anche una tabella di DynamoDB<\/strong> per contenere i metadati e le informazioni di share dei file. Procediamo quindi alla creazione di una tabella lasciando i valori di default e specificando \u201cshareID\u201d come chiave di partizione primaria.<\/span><\/p>\n

      \"\"<\/p>\n

      A questo punto dobbiamo occuparci di Cognito<\/strong> e di API Gateway<\/strong>. Il primo \u00e8 necessario per la parte di autenticazione, ed il secondo permetter\u00e0 al front-end di accedere alle funzionalit\u00e0 del back-end lambda mediante chiamate https.<\/span><\/p>\n

      Per prima cosa creiamo e configuriamo una Cognito User Pool<\/strong>.<\/span><\/p>\n

      Durante il Wizard di creazione possiamo personalizzare alcuni comportamenti; per far funzionare l\u2019applicazione bisogna creare un Pool che permetta gli utenti di registrarsi mediante email e di verificare l\u2019indirizzo utilizzando un codice di sicurezza gestito da Cognito. Occorre anche creare un\u2019app client e prendere nota del suo ID.<\/span><\/p>\n

      Scegliamo un nome per la User Pool e avviamo il wizard<\/span><\/p>\n

      \"\"<\/p>\n

      Configuriamo il meccanismo di autenticazione e i campi del profilo.<\/span><\/p>\n

      \"\"<\/p>\n

      Infine bisogna creare un app client e prendere nota del suo ID. Non bisogna far generare alcun segreto, non servir\u00e0 per l\u2019utilizzo di Cognito mediante web app.<\/span><\/p>\n

      \"\"<\/p>\n

      \"\"<\/p>\n

      Con Cognito abbiamo finito per ora, queste risorse saranno utilizzate dall\u2019applicazione e da API Gateway per il meccanismo di autenticazione.<\/span><\/p>\n

      Infine procediamo alla creazione di una API su API Gateway.<\/span><\/p>\n

      Questo componente fa da interfaccia tra le richieste dell\u2019utente e la funzione lambda, inoltre si occuper\u00e0 in modo automatico dell\u2019autenticazione delle richieste mediante la user pool di Cognito. <\/span><\/p>\n

      Per scopo di test procediamo alla creazione di una API semplice con soltanto un metodo GET che chiama la funzione lambda.<\/span><\/p>\n

      \"\"<\/p>\n

      Una volta configurata l\u2019integrazione \u00e8 possibile testarla<\/span><\/p>\n

      \"\"<\/p>\n

      Nell\u2019ultimo articolo della serie ci occuperemo della parte applicativa<\/strong> e della pipeline di CD\/CI<\/strong>, e vedremo come integrare Cognito in API Gateway<\/strong> per beneficiare dell\u2019autenticazione automatica.<\/span><\/p>\n

      Stay tuned! \ud83d\ude42<\/span><\/p>\n

      Leggi la prima parte<\/a> | Leggi la terza parte<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

      Leggi la prima parte | Leggi la terza parte Con la sempre maggiore diffusione dello sviluppo Serverless, \u00e8 di fondamentale […]<\/p>\n","protected":false},"author":6,"featured_media":362,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[477],"tags":[263,364,360,267],"yoast_head":"\nGo Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing - Proud2beCloud Blog<\/title>\n<meta name=\"description\" content=\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\" \/>\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\/go-serverless-pt2\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\" \/>\n<meta property=\"og:description\" content=\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/\" \/>\n<meta property=\"og:site_name\" content=\"Proud2beCloud Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-25T10:48:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-03-17T11:13:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2018\/09\/SERVERLESS-02.png\" \/>\n\t<meta property=\"og:image:width\" content=\"4267\" \/>\n\t<meta property=\"og:image:height\" content=\"3200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alessandro Gaggia\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\" \/>\n<meta name=\"twitter:description\" content=\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alessandro Gaggia\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/\",\"url\":\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/\",\"name\":\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing - Proud2beCloud Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\"},\"datePublished\":\"2018-09-25T10:48:07+00:00\",\"dateModified\":\"2021-03-17T11:13:22+00:00\",\"author\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/f27fc12d10867c6ea6e0158ce4dd8924\"},\"description\":\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.besharp.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing\"}]},{\"@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\/f27fc12d10867c6ea6e0158ce4dd8924\",\"name\":\"Alessandro Gaggia\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f58dc28050f26409e22ab60346d06220?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f58dc28050f26409e22ab60346d06220?s=96&d=mm&r=g\",\"caption\":\"Alessandro Gaggia\"},\"description\":\"Head of software development di beSharp, Full-Stack developer, mi occupo di garantire lo stato dell\u2019arte di tutta la nostra codebase. Scrivo codice in quasi ogni linguaggio, ma prediligo Typescript. Respiro Informatica, Game design, Cinema, Fumetti e buona cucina. Disegno per passione!\",\"url\":\"https:\/\/blog.besharp.it\/it\/author\/alessandro-gaggia\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing - Proud2beCloud Blog","description":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","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\/go-serverless-pt2\/","og_locale":"it_IT","og_type":"article","og_title":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","og_description":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","og_url":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/","og_site_name":"Proud2beCloud Blog","article_published_time":"2018-09-25T10:48:07+00:00","article_modified_time":"2021-03-17T11:13:22+00:00","og_image":[{"width":4267,"height":3200,"url":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2018\/09\/SERVERLESS-02.png","type":"image\/png"}],"author":"Alessandro Gaggia","twitter_card":"summary_large_image","twitter_title":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","twitter_description":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","twitter_misc":{"Scritto da":"Alessandro Gaggia","Tempo di lettura stimato":"6 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/","url":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/","name":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing - Proud2beCloud Blog","isPartOf":{"@id":"https:\/\/blog.besharp.it\/it\/#website"},"datePublished":"2018-09-25T10:48:07+00:00","dateModified":"2021-03-17T11:13:22+00:00","author":{"@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/f27fc12d10867c6ea6e0158ce4dd8924"},"description":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione Serverless di file sharing.","breadcrumb":{"@id":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.besharp.it\/it\/go-serverless-pt2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.besharp.it\/it\/"},{"@type":"ListItem","position":2,"name":"Go Serverless! Parte 2: l\u2019infrastruttura per l\u2019applicazione di file sharing"}]},{"@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\/f27fc12d10867c6ea6e0158ce4dd8924","name":"Alessandro Gaggia","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f58dc28050f26409e22ab60346d06220?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f58dc28050f26409e22ab60346d06220?s=96&d=mm&r=g","caption":"Alessandro Gaggia"},"description":"Head of software development di beSharp, Full-Stack developer, mi occupo di garantire lo stato dell\u2019arte di tutta la nostra codebase. Scrivo codice in quasi ogni linguaggio, ma prediligo Typescript. Respiro Informatica, Game design, Cinema, Fumetti e buona cucina. Disegno per passione!","url":"https:\/\/blog.besharp.it\/it\/author\/alessandro-gaggia\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/284"}],"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\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/comments?post=284"}],"version-history":[{"count":0,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/284\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media\/362"}],"wp:attachment":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media?parent=284"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/categories?post=284"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/tags?post=284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}