{ "type": [ "h-entry" ], "properties": { "syndication": [ "https://twitter.com/barryf/status/1415033757661270018" ], "name": [ "My serverless, headless, Micropub-powered, personal website" ], "published": [ "2021-07-13T19:23:03.696Z" ], "category": [ "serverless", "cms", "architect", "micropub", "indieweb", "personal" ], "post-status": [ "published" ], "updated": [ "2021-07-14T08:26:24.403Z" ], "content": [ "**TL;DR** *This is my new personal [IndieWeb](https://indieweb.org/) website built using serverless AWS services, written in Node.js with the [Architect framework](https://arc.codes/). The backend is a [Micropub](https://micropub.net/) server with a separate frontend that fetches posts using Micropub queries, rendering pages behind a CDN.*\r\n\r\nLook, I know it’s a developer cliché for the majority of posts on your blog to be about rewriting your own personal website software, but I find my website is the perfect place to try out new technology and then document what I’ve learned.\r\n\r\nSo, yes, this is a blog post about my new website. As well as a refreshed design, it’s completely different behind the scenes. The project is called [Vibrancy](https://github.com/barryf/vibrancy). It’s massively over-engineered! But that’s the point: learn, have fun and enjoy slowly hacking away after the kids go to bed.\r\n\r\n## Goals\r\n\r\n- **Instant updates**. My website has over 10K posts and even the fastest static site generators take ~10 seconds to build and deploy so many files. I want the time between hitting create/update and the page refreshing to be instant.\r\n- **Save money**. My [previous](https://barryfrost.com/2016/11/colophon), low-traffic website cost $16/month on Heroku for a Hobby tier dyno, plus a PostgreSQL database with over 10K rows. I love Heroku, but that’s a bit much for my little website. I wanted my website to cost a few dollars on AWS, after the [always free](https://aws.amazon.com/free/) limits.\r\n- **Use new (to me) technology:**\r\n - **Serverless**: My website doesn't get much traffic and having an always-on server seemed wasteful. It seemed like a good use-case for trying small, stateless Node.js functions that can be called on-demand without reserving compute.\r\n - **AWS**: While I’d used EC2 and S3 before, I wanted to experiment with other AWS services like Lambda, API Gateway, DynamoDB, SNS and CloudWatch that complement a serverless approach.\r\n - **Node.js**: Ruby is a comfortable pair of shoes. I used it for previous versions of this website and it felt like time for a change. Node.js is a well-supported choice for Serverless.\r\n\r\n## Framework\r\n\r\nI’m using [Architect](https://arc.codes/) for both the backend and frontend apps. I spent some time prototyping with the [Serverless Framework](https://www.serverless.com/), but was left frustrated at its incomplete support for local development. This is where Architect [shines](https://arc.codes/docs/en/guides/get-started/why-architect):\r\n\r\n> Architect is an opinionated developer experience (DX) for building database backed web apps with AWS. We remove all the noise and friction to building serverlessly. We prioritize speed with fast local dev, smart configurable defaults and flexible Infrastructure as Code.\r\n\r\nAt its core is the [app.arc manifest file](https://arc.codes/docs/en/guides/get-started/project-layout) and a file structure based around primitives for HTTP requests, events, queues, scheduled tasks, tables, static files and more. Each maps to an AWS service, for example `tables` corresponds to DynamoDB tables and `queues` to SQS. Architect then provides helpers to simplify working with each service. And by running `arc deploy`, it builds a SAM application that is magically deployed via CloudFormation to AWS.\r\n\r\nArchitect has been a breath of fresh air and reminds me of how natural Rails felt the first time I tried it. It deserves a proper article.\r\n\r\n## Backend\r\n\r\n![Backend architecture](https://barryf.s3.eu-west-1.amazonaws.com/vibrancy-backend.png)\r\n\r\n*Vibrancy's backend architecture, hosted using AWS.*\r\n\r\n### Headless CMS\r\n\r\nI like the concept of separating the management of my content from its display by adopting a [headless CMS](https://en.wikipedia.org/wiki/Headless_content_management_system) architecture. In theory, I‘m free to build multiple frontends that all use the same backend. There are plenty of excellent headless CMS options, but I built my own. Why? Well, I wanted to embrace the constraints of managing content exclusively via [Micropub](https://micropub.net/).\r\n\r\nBy implementing the Micropub server specification, Vibrancy has a mature, well-documented API for creating, updating, deleting, reading and querying posts. There is no admin system. Instead, using a Micropub client like [Micropublish](https://micropublish.net/) or [Quill](https://quill.p3k.io/), I can log in (via [IndieAuth](https://www.w3.org/TR/indieauth/)) and manage my content.\r\n\r\n### Media endpoint\r\n\r\nVibrancy offers a [Micropub media endpoint](https://indieweb.org/micropub_media_endpoint): a method to upload images and get a URL for use in posts. [Cloudinary](https://cloudinary.com) is used to upload, store and serve photos. Its ability to dynamically-resize images means I can upload one large file and then request different sizes on the fly, keeping frontend page sizes down. Images are then also uploaded to GitHub.\r\n\r\n### Background events\r\n\r\nUsing Architect’s `event` handlers, the server fires off asynchronous tasks in the background to avoid blocking page requests. Lambda functions are handled using SNS.\r\n\r\n- **Syndication**: if specified when I create a post, the backend will [POSSE](https://indieweb.org/POSSE) notes to Twitter and bookmarks to [Pinboard](http://pinboard.in/).\r\n- **Webmentions**: when a post is created or updated, the server will send [webmentions](https://webmentions.net/) to any links using [Telegraph](https://telegraph.p3k.io).\r\n- **Backup**: all posts, webmentions and photos are also stored in a private git repo on GitHub.\r\n- **Contexts**: to display a snippet of the source of any bookmarks, RSVPs, replies, reposts or likes, the server uses [Granary](http://granary.io/) to fetch structured data in Microformats format and falls back to Open Graph metadata.\r\n- **Push**: the server uses [Pushover](https://pushover.net) to send me a push notification whenever a webmention is received.\r\n\r\n### Storage\r\n\r\n- **DynamoDB**: Content is indexed and stored in AWS’s DynamoDB. It’s a fast, low-latency database and its `tables` are a core primitive in Architect. I’m reasonably happy with it, but found the need to create extra tables a bit dirty when trying to combine filters with pagination. It was worth embracing its differences and learn its constraints to follow the Architect happy path.\r\n- **GitHub**: Content is also stored in a git repository on GitHub as a backup. If needed, I could regenerate the DynamoDB database from the repo. I’ve chosen to make the repo private because it’s possible some posts may be private or start off as drafts.\r\n- **Cloudinary**: As described above, photos are stored in Cloudinary and served from its CDN.\r\n\r\n## Frontend\r\n\r\n![Frontend architecture](https://barryf.s3.eu-west-1.amazonaws.com/vibrancy-frontend.png)\r\n\r\n*Vibrancy’s frontend architecture, hosted using AWS and Cloudflare.*\r\n\r\n### Micropub queries\r\n\r\nThe frontend website doesn’t have a database or any content files of its own. Instead, when a post is requested, a Micropub `source` query is made to the backend and the post is returned in [Microformats 2 JSON](http://microformats.org/wiki/microformats2-json) format.\r\n\r\n```json\r\n// Request for https://barryfrost.com/2021/07/a-post\r\nGET https://api.barryfrost.com/micropub?q=source&url=https://barryfrost.com/2021/07/a-post\r\n{\r\n \"type\": [\r\n \"h-entry\"\r\n ],\r\n \"properties\": {\r\n \"published\": [\r\n \"2021-07-01T12:34:56Z\"\r\n ],\r\n \"content\": [\r\n \"This is my post. I use *Markdown* to mark up text.\"\r\n ]\r\n }\r\n}\r\n```\r\n\r\nThe frontend takes this JSON object and renders a page using [Nunjucks](https://mozilla.github.io/nunjucks/) templates. It also converts Markdown to HTML if needed.\r\n\r\nLists of posts are also fetched in the same way, but with additional parameters to filter results:\r\n\r\n- `before` takes an integer representing the epoch time of a post’s published timestamp. This method is used to paginate results.\r\n- `limit` is the number of posts to return in the response, defaulted to 20.\r\n\r\nLike the backend, the frontend uses the Architect framework.\r\n\r\n### Style\r\n\r\nThis is the first project on which I’ve used [Tailwind CSS](https://tailwindcss.com). Initially it felt like [heresy](https://barryfrost.com/2020/11/i-ve-been-using-tailwindcss-for), but I quickly began to enjoy how fast it was to build solid, responsive layouts without needing to bounce back-and-forth between HTML and CSS files. Tailwind also provides a built-in dark mode with very little configuration.\r\n\r\nI’m using inline SVGs for icons instead of an icon font to help further decrease page load times.\r\n\r\n### CDN\r\n\r\nThe frontend is not static. It queries and renders pages on demand. However, posts are cached and served using Cloudflare’s CDN (Content Delivery Network). I use very long `s-maxage` cache headers for posts which mean that requests are less likely to hit the frontend. If a post is updated Vibrancy sends a flush API request to Cloudflare.\r\n\r\n## Webmentions\r\n\r\nVibrancy fully supports [webmentions](https://webmentions.net/) for replies, reposts, likes or mentions from another IndieWeb website or service.\r\n\r\n- **Receiving**: Vibrancy currently uses [webmention.io](http://webmention.io) to receive webmentions, accepting a Microformats payload using a webhook. Next on my list is [building my own receiver](/2021/05/building-a-webmention-receiver).\r\n- **Sending**: Webmentions are sent via [Telegraph](https://telegraph.p3k.io) using a background event whenever a post is created or updated.\r\n- **Backfeed**: Using the magic of [Bridgy](https://brid.gy/), responses to my syndicated copies (e.g. tweets) are pulled back as webmentions.\r\n\r\n## Open source\r\n\r\nVibrancy’s source code is available on GitHub for both the [backend](https://github.com/barryf/vibrancy) and [frontend](https://github.com/barryf/barryfrost) using the [MIT licence](https://opensource.org/licenses/MIT). Feel free to poke around, but I’m still actively developing and improving it and I wouldn’t recommend using Vibrancy for your own site just yet." ], "like": [ { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-1261782769" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Jiazhen Xie" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/cd5714d9dfb4e2e0b9c526bd6f84df2d49239a9bdbb7765d0be53724ebe8c228.jpg" ], "url": [ "https://twitter.com/JIAZHENXIE" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-13T21:46:00+01:00" ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://www.jvt.me/mf2/2021/07/bpzf0/" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Jamie Tanna" ], "photo": [ "https://webmention.io/avatar/www.jvt.me/f0f487b73880b54411ec067322d1d32edcb4b125853353123e076183d1131acf.png" ], "url": [ "https://www.jvt.me" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-434457570" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Ana Rodrigues" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/fc885e5ff4cb71287c4384f7b208bb425af1a7a3139bbd8baf8f11923e168aa2.jpg" ], "url": [ "https://twitter.com/ohhelloana" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T11:00:00+01:00" ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://calumryan.com/likes/3531" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Calum Ryan" ], "photo": [ "https://webmention.io/avatar/calumryan.com/63f5cb9b1f74b3939cb54d2c61ed099619fc2817968259fd07162ecd6d8da085.png" ], "url": [ "https://calumryan.com/" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-6187652" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Michael Bishop" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/2c068cafaa5ac4bdb9ae95f69642dfc406f2164de028304d0bb66ba200269bb5.jpg" ], "url": [ "https://twitter.com/miklb" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-231445532" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Johan Bové" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/bd2ec422c37d37deb47df70038409b1cb1a8c515db3875c0997e42f692e9e005.jpg" ], "url": [ "https://twitter.com/johanbove" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-827309696910446598" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Kylin King" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/70b9a0b37f459f1557c60679f293ee00f94c36005c679ef978ac2b013180c36f.jpg" ], "url": [ "https://twitter.com/ycjcl" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-18T11:44:39-04:00" ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://martymcgui.re/2021/07/18/114439/" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Marty McGuire" ], "photo": [ "https://webmention.io/avatar/martymcgui.re/f750b9918a92f3dc86d15d8fefad4a06c20a829ae950e18dfc2c8b9a4b26b422.jpg" ], "url": [ "https://martymcgui.re/" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-6758842" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "daiyi! ✨ (chris)" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/b90c7c5ab2243a5271925590bfcdb0ea18137686dd0353723fdc99f1eeae98c1.jpg" ], "url": [ "https://twitter.com/daiyitastic" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-1144584487" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Patrick Dung" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/f6f3f84aa8cfdf456c14c169fb3a5a72e3d0bc94cbefc1434ae1d9d9ff380b97.jpg" ], "url": [ "https://twitter.com/mpatdung" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1415033757661270018#favorited-by-2767528943" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Alex Madesclaire ⚪" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/d9c1c2f7c450999a6192f6e18f5fb1e4554c91b629783c72519d8948e8815bbe.jpg" ], "url": [ "https://twitter.com/amadesclaire" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-676363" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Brian LeRoux" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/66668b8dccc6a13a0a207b2219cedf8ca8da93a11b4f8b2c9ac5bd0a3a7871c3.jpg" ], "url": [ "https://twitter.com/brianleroux" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-146569131" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "aaron hans" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/41a9217e31214dedee28ad124b38199b63e1aae50cca12f3cd82352d4c216b0f.png" ], "url": [ "https://twitter.com/nopatternaaron" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-2260815740" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Jake" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/55452fdbb1b010495f28472fab8127f5c5d5ed7aa4f83162020af3774bb163a8.jpg" ], "url": [ "https://twitter.com/JakeDChampion" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-22651735" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Fil Maj" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/59b192bd16f01a6d5d0888e745df58df216389a339a504f01e523a8c97d5996e.jpg" ], "url": [ "https://twitter.com/filmaj" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-7661142" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Kristofer Joseph" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/f731702512b491fb3219f8a78bf3c5027b4e4d2629b8289f691e21444debb838.jpg" ], "url": [ "https://twitter.com/dam" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "like-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/barryf/status/1531350008074752001#favorited-by-28303561" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Klaas Cuvelier" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/6625d36a090d4c235fe643420ea1d561b0fb43dbb9daf13d6f69be48b4c32d75.jpg" ], "url": [ "https://twitter.com/klaascuvelier" ] } } ] } } ], "repost": [ { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "repost-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://lobste.rs/s/joaeuw" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Jamietanna" ], "photo": [ "" ], "url": [ "https://lobste.rs/u/Jamietanna" ] } } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T21:23:43+00:00" ], "repost-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/cswordpress/status/1415421778743156738" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Amanda J. caarson" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/f857ae597fa2ca438c5d8450fd707a8a8f9f2d48ea6295797a96a9c8d453e68b.jpg" ], "url": [ "https://twitter.com/cswordpress" ] } } ], "content": [ "✍️My new personal #indieweb website using all the buzzwords barryfrost.com/2021/07/vibran…" ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-16T14:03:57+00:00" ], "repost-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/Cambridgeport90/status/1416035883359215619" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Kat M. Moss" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/da00ef9bad5913bbf8db858e41be8b8f2fecd7ef5c770d8a52071233cf519e49.jpg" ], "url": [ "https://twitter.com/Cambridgeport90" ] } } ], "content": [ "✍️My new personal #indieweb website using all the buzzwords barryfrost.com/2021/07/vibran…" ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2022-05-31T15:53:37+00:00" ], "repost-of": [ "https://barryfrost.com/2021/07/vibrancy" ], "url": [ "https://twitter.com/dam/status/1531665207822385153" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Kristofer Joseph" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/f731702512b491fb3219f8a78bf3c5027b4e4d2629b8289f691e21444debb838.jpg" ], "url": [ "https://twitter.com/dam" ] } } ], "content": [ "If you and @filmaj are interested in this stuff you could have a poke around my Architect-powered IndieWeb backend and website. github.com/barryf/vibrancy barryfrost.com/2021/07/vibran…" ] } } ], "comment": [ { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-14T08:25:10+00:00" ], "url": [ "https://twitter.com/ohhelloana/status/1415225849893228545" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Ana Rodrigues" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/fc885e5ff4cb71287c4384f7b208bb425af1a7a3139bbd8baf8f11923e168aa2.jpg" ], "url": [ "https://twitter.com/ohhelloana" ] } } ], "content": [ { "html": [ "Oh wow that’s great!!! Lots for me to learn from!\n\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-14T16:56:47Z" ], "url": [ "https://jlelse.blog/micro/2021/07/2021-07-14-vqmex" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "jlelse's Blog" ], "photo": [ "https://webmention.io/avatar/jlelse.dev/ff05769865d92301fe7b12f64789769aa82531fe3ba4d4821cf140474380a848.png" ], "url": [ "https://jlelse.blog" ] } } ], "content": [ { "html": [ "
This is a nice read! What do you think about vendor lock-in (everything is based on AWS and a few other proprietary services) and how much does it cost you per month (is it cheaper than your previous Heroku setup)?
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-14T17:51:22" ], "url": [ "https://barryfrost.com/2021/07/thanks-jan-lukas-i-m-pretty" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Barry Frost" ], "photo": [ "https://webmention.io/avatar/barryfrost.com/f14d57ed2a3d82873ea65bc43217bacb3241414afdd99657c4dbde872e85afe0.jpg" ], "url": [ "https://barryfrost.com/" ] } } ], "content": [ { "html": [ "Thanks, Jan-Lukas. I’m pretty happy with AWS and I don’t think I would want to switch away. It’s more likely I will rewrite again someday! Thinking of AWS as a framework itself resonates with me. In terms of costs, outside the generous “always free” Lambda and SNS limits, I’m currently paying about $1/month for API Gateway and DynamoDB usage.
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-18T06:35:16+00:00" ], "url": [ "https://twitter.com/ycjcl/status/1416647740390469632" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Kylin King" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/70b9a0b37f459f1557c60679f293ee00f94c36005c679ef978ac2b013180c36f.jpg" ], "url": [ "https://twitter.com/ycjcl" ] } } ], "content": [ { "html": [ "JAMStack~\n\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-26T17:08:49+01:00" ], "url": [ "https://rowanmanning.com/notes/3/" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Rowan Manning" ], "photo": [ "https://webmention.io/avatar/rowanmanning.com/7e3fc708e033a6bc9368df7540d9bf26759118fcb7bf87ca72dafcc454249780.png" ], "url": [ "https://rowanmanning.com/" ] } } ], "content": [ { "html": [ "This is an interesting read, it gave me a lot of ideas for how I might self-host the parts of my website which currently use third-party services. I might play with Architect when I get a chance.
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2021-07-26T20:52:15" ], "url": [ "https://barryfrost.com/2021/07/thanks-very-much-rowan-let-me" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Barry Frost" ], "photo": [ "https://webmention.io/avatar/barryfrost.com/f14d57ed2a3d82873ea65bc43217bacb3241414afdd99657c4dbde872e85afe0.jpg" ], "url": [ "https://barryfrost.com/" ] } } ], "content": [ { "html": [ "Thanks very much, Rowan. Let me know if you’ve any questions about it. Architect is definitely worth having a poke around.
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:01:06" ], "url": [ "https://barryfrost.com/2022/05/brianleroux-if-you-and-filmaj-are" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Barry Frost" ], "photo": [ "https://webmention.io/avatar/barryfrost.com/f14d57ed2a3d82873ea65bc43217bacb3241414afdd99657c4dbde872e85afe0.jpg" ], "url": [ "https://barryfrost.com/" ] } } ], "content": [ { "html": [ "@brianleroux If you and @filmaj are interested in this stuff you could have a poke around my Architect-powered IndieWeb backend and website. https://github.com/barryf/vibrancy https://barryfrost.com/2021/07/vibrancy
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:03:17+00:00" ], "url": [ "https://twitter.com/brianleroux/status/1531350554508636160" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Brian LeRoux" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/66668b8dccc6a13a0a207b2219cedf8ca8da93a11b4f8b2c9ac5bd0a3a7871c3.jpg" ], "url": [ "https://twitter.com/brianleroux" ] } } ], "content": [ { "html": [ "Oh wat! I'm mid flight in a clean implementation myself rn. This is awesome!\n\n\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:08:09+00:00" ], "url": [ "https://twitter.com/barryf/status/1531351778704359425" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Barry Frost" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/dca33e28a4c1fbc65487d0d2b72032d54aee7a8350bb43bd092c4ea217e09561.jpg" ], "url": [ "https://twitter.com/barryf" ] } } ], "content": [ { "html": [ "Nice! Feel free to copy any code, or shout if you have IndieWeb questions 😁\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:09:34+00:00" ], "url": [ "https://twitter.com/brianleroux/status/1531352135543054336" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Brian LeRoux" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/66668b8dccc6a13a0a207b2219cedf8ca8da93a11b4f8b2c9ac5bd0a3a7871c3.jpg" ], "url": [ "https://twitter.com/brianleroux" ] } } ], "content": [ { "html": [ "will do, should have an alpha ready indieauth plugin this week 👍 \n\nlooking at pub/sub/mention next\n\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:11:44+00:00" ], "url": [ "https://twitter.com/barryf/status/1531352678365810690" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Barry Frost" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/dca33e28a4c1fbc65487d0d2b72032d54aee7a8350bb43bd092c4ea217e09561.jpg" ], "url": [ "https://twitter.com/barryf" ] } } ], "content": [ { "html": [ "Excited to see it. Architect is the perfect framework for these type of services (as you know!)\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "in-reply-to": [ "https://barryfrost.com/2021/07/vibrancy" ], "published": [ "2022-05-30T19:23:13+00:00" ], "url": [ "https://twitter.com/filmaj/status/1531355567427670016" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Fil Maj" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/59b192bd16f01a6d5d0888e745df58df216389a339a504f01e523a8c97d5996e.jpg" ], "url": [ "https://twitter.com/filmaj" ] } } ], "content": [ { "html": [ "Great stuff!\n\n\n" ] } ] } } ], "mention": [ { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T14:50:19+00:00" ], "url": [ "https://twitter.com/lobsters/status/1415322773061308426" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Lobsters" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/e3268170b54c9161a592561cbf819dacf562412f24ea1437f5afa36fc4f69bba.jpg" ], "url": [ "https://twitter.com/lobsters" ] } } ], "content": [ { "html": [ "My serverless, headless, Micropub-powered, personal website\nlobste.rs/s/joaeuw #api #devops #javascript #scaling #web\nbarryfrost.com/2021/07/vibran…" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T19:23:14+02:00" ], "url": [ "https://jlelse.blog/micro/2021/07/2021-07-14-snooq" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "jlelse's Blog" ], "photo": [ "https://webmention.io/avatar/jlelse.dev/ff05769865d92301fe7b12f64789769aa82531fe3ba4d4821cf140474380a848.png" ], "url": [ "https://jlelse.blog" ] } } ], "content": [ { "html": [ "Now that I have the option to publish posts without them showing up in the feed for everyone, I can finally use my blog to comment on other IndieWeb sites and send webmentions without annoying my followers. Now my blog is really a complete Twitter replacement for me.
\nOne post I commented on, for instance, is Barry Frost’s article about his new IndieWeb CMS. A different approach than mine.
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T20:57:00+00:00" ], "url": [ "https://twitter.com/ChrisShort/status/1415415054296653827" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Chris Short" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/1d87ebe3cd72a6ded599f8f75d97e00fe151f6ab050dbd10859f7a8b850513ec.jpg" ], "url": [ "https://twitter.com/ChrisShort" ] } } ], "content": [ { "html": [ "Recommended Read: My serverless, headless, Micropub-powered, personal website barryfrost.com/2021/07/vibran…" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2021-07-14T23:03:02+00:00" ], "url": [ "https://twitter.com/ibrahimcesar/status/1415446771552210945" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Ibrahim Cesar" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/c1c709f166194c19a8b08a63af902365bcb64c9ddd1022459912675462f7691a.jpg" ], "url": [ "https://twitter.com/ibrahimcesar" ] } } ], "content": [ { "html": [ "My serverless, headless, Micropub-powered, personal website — Barry Frost barryfrost.com/2021/07/vibran…" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [ "Bookmark on 14th March 2022 @ 17:15" ], "published": [ null ], "url": [ "https://www.synesthesia.co.uk/stream/bookmark-on-14th-march-2022-1715/" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "" ], "photo": [ "" ], "url": [ "" ] } } ], "content": [ { "html": [ "Lots of ideas here, and a great example of how, in return for committing to the services from a specific cloud vendor, you can build some really smart application architecture.
" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ "2022-05-30T19:04:16+00:00" ], "url": [ "https://twitter.com/brianleroux/status/1531350801775333376" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "Brian LeRoux" ], "photo": [ "https://webmention.io/avatar/pbs.twimg.com/66668b8dccc6a13a0a207b2219cedf8ca8da93a11b4f8b2c9ac5bd0a3a7871c3.jpg" ], "url": [ "https://twitter.com/brianleroux" ] } } ], "content": [ { "html": [ "I 💗 the app.arc file is so *clear* what this does, and how.\n\n" ] } ] } }, { "type": [ "h-cite" ], "properties": { "name": [], "published": [ null ], "url": [ "https://www.reddit.com/r/devopsish/comments/ok8bh6/my_serverless_headless_micropubpowered_personal/" ], "author": [ { "type": [ "h-card" ], "properties": { "name": [ "" ], "photo": [ "" ], "url": [ "" ] } } ] } } ] } }