Using the Serverless framework to add your Medium feed to a website

Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform. By using these ideas, and related ones like single-page applications, such architectures remove much of the need for a traditional always-on server component — Martin Fowler (Symphonia)

Because CORS (You know that thing that keeps your site, and you on sites, safe) is a thing, you can’t pull your Medium feed directly from another website.

What is needed is a proxy, a piece of code in the cloud that does this on your behalf, in a secure and scalable way.

In this tutorial I am using Amazon’s AWS Lambda, but you could just as easily use Microsoft’s Azure Functions or Google’s Cloud Functions.

Requirements

Getting Started

Firstly, you’d want to install the serverless framework globally like so:

npm i -g serverless

Once installed, you need to create a new serverless project like so:

sls create --template aws-nodejs --path sls-medium-feed

This creates a folder named sls-medium-feed in the current directory with a basic “hello world” setup.

Next, you want to install a plugin to develop locally until you are ready to deploy to the actual cloud.

First create a local npm package (You can just press enter to all the questions npm asks you — or you can fill them in)

cd sls-medium-feed; npm init; // on MacOS or Linux
cd sls-demium-feed && npm init // on Windows

Now let’s install the Serverless offline plugin :

npm i serverless-offline --save-dev

The save-dev part tells npm to add this package to the developer dependencies section of your package.json file as it will obviously not be required in production.

Next you need to add this plugin to your serverless.yml file like so (I stripped mine of comments for illustrative purposes — but they are worth a read):

service: sls-medium-feed
provider:
name: aws
runtime: nodejs8.10
functions:
hello:
handler: handler.hello
plugins:
- serverless-offline

Right. So let’s test if everything works by simply running the sls command in the directory:

You should now see that offline commands have been added to serverless runtime options

You will see you now have the offline start command available. So let’s test that :

It works!

Right. So let’s hook up the “hello world” handler to test. Change your serverless.yml file to look like this:

service: sls-medium-feed
provider:
name: aws
runtime: nodejs8.10
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
plugins:
- serverless-offline

And rerun sls offline start

Since we configured the function to be available via http GET call, you can simply load up http://localhost:3000/hello in a browser:

I am using a JSON Formatter plugin for Chrome to prettify JSON responses .

So as you can see, besides the actual response (in the message field) there is a while bunch of other data in the response. You can map this to what you find in the handler.js file :

As you can see, this function echoes back all the event data in the input field.

You obviously don’t want to do this in production unless you have a good reason…

Right, so with our basic Serverless pipeline working, let’s move on to the actual proxy implementation.

Developing the Proxy

I am just going to re-use the created hello function and change the plumbing slightly.

My serverless.yml file now looks like this:

service: sls-medium-feed
provider:
name: aws
runtime: nodejs8.10
functions:
fetch:
handler: handler.fetch
events:
- http:
path: fetch
method: get
cors: true
plugins:
- serverless-offline
Take note of the cors:true flag

In addition, my handler.js is now cleaned, exports the fetch endpoint, and ready for new code:

Source code can be found by following the GitLab link at the end of this post

Before we continue, let’s first install the Nodejs request module in order to make HTTP requests from our function:

npm i request

and an RSS to JSON parser (As the feed is returned from Medium as RSS XML) — This step is optional, as you may want to consume an RSS feed on your site — although it will require slightly different code. Personally, I prefer JSON all the way.

npm i feedme

Once done, we are ready to fetch our feed.

You can access your Medium feed by loading the following url (replacing username with your actual username:

https://medium.com/feed/@username

So in my case it would be :

https://medium.com/feed/@k1d_bl4ck

Right, so let’s go fetch this by adding the following to our handler:

Source code can be found by following the GitLab link at the end of this post
  • Notice how I have set both cors:true in the serverless.yml file (a few steps back), as well as added CORS access control headers (lines 10 and 11) to the response in the function itself.
  • cors:true tells the AWS API Gateway that this endpoint may be CORS enabled, yet you still have to specify the headers as you require them in your actual function responses.

So, let’s restart serverless again, and load http://localhost:3000/fetch in the browser. The result is :

Great success!!

So there we have it, a simple cloud function that proxies a medium feed to whoever calls it.

Now for the last step, deploying this to the cloud so you can call it from your site.

Deploying to Cloud

First, in the case of using AWS Lambda (which I do here), you need to export your AWS access key and secret into your environment. There are many ways to do this, but for this tutorial, we will simply run the following:

export AWS_ACCESS_KEY_ID=<your-key-here> 
export AWS_SECRET_ACCESS_KEY=<your-secret-key-here>
You can read more about setting up AWS credentials on the Serverless documentation page here

So now that we have our credentials set, let’s deploy our function:

sls deploy

After engaging with the gods of the Internet for a few seconds, you should see something like the following output :

Your lambda function is active and ready to call

Loading the provided endpoint in the browser gives, surprise surprise, the same response we got on our localhost.

With everything now working, let’s add the final touches by configuring our function resources, and deploying to production.

service: sls-medium-feed
provider:
name: aws
runtime: nodejs8.10
memorySize: 128
timeout: 10
stage: prd
region: eu-west-1
functions:
fetch:
handler: handler.fetch
events:
- http:
path: fetch
method: get
cors: true
plugins:
- serverless-offline

Here we add max memory the lambda can consume, set the timeout, and configure the stage to prd.

Notice we initially deployed this as a dev stage. A stage in Serverless scopes your endpoints so that you can stage your releases to test, pass QA, and eventually deploy into production.

Easy peasy lemon squeezy.

So another…

sls deploy

and we are all set.

We now have a dev and a prd stage, so any changes can be tested in the cloud without disrupting the prd stage until you are ready.

How to use?

So now that you can pull your Medium feed, what do you do with it? Well… read my post on rendering the JSON you get from the proxy with vue.js

And that’s it for now… thanks for reading!

Source Code