A Serverless Jukebox app built using AWS Lambda, React, GraphQL, API Gateway and Node.js. You can search for songs using the Last.fm api and save the names of songs you like to a playlist.
- GraphQL
- AWS Lambda - hosts the GraphQL server
- AWS API Gateway - expose a public HTTP endpoint for the GraphQL lambda
- Node.js
This repo has all the code for the GraphQL Lambda function and creation of an s3 bucket and API Gateway endpoint connected to the lambda function.
In addition to the GraphQL Lambda there are three other lambda functions
- song-suggester - Queries the Last.fm api to retrieve song suggestions
- s3-save - Saves a selected song to an s3 bucket
- s3-get - Retrieves all songs from an s3 bucket
The GraphQL IDE and UI live here: https://github.com/nikhilaravi/serverless-graphql-app
- Create an account on Amazon
- Get your access key id and secret access key. Give your user super access - add an administrator access policy so you can create lambdas, api endpoints etc using the aws-cli.
- Install the aws-cli and configure it with your credentials by typing
aws configure
and pressing Enter. This interactive command will prompt you for your access keys and region. - Get a last.fm api key by creating an account https://secure.last.fm/login?next=/api/account/create
Add the following environment variables to a .env file
AWS_ACCOUNT_ID=[your_account_id_here]
AWS_ACCESS_KEY_ID=[your_key_here]
AWS_SECRET_ACCESS_KEY=[your_secret_here]
AWS_REGION=[aws_region] (e.g. 'eu-west-1')
API_KEY=[lastfm_api_key]
AWS requires you to specify the permissions which are given to different resources e.g. who can view the objects inside an s3 bucket, who can invoke a lambda function etc.
These permissions are defined as policies and for different IAM roles which can then be assigned to different services or external services like CodeShip.
npm run create-iam
This will create an iam role for the lambda function and print it in the terminal.
Export this as an environment variable. This role will be used by the deploy script.
export AWS_IAM_ROLE="arn:account_id:role_name"
When a track is added to the playlist, it will be saved as a json file in s3. An s3 bucket needs to be created and given permission to be modified by other AWS services (i.e. permission to allow our Lambda to write and read from it).
Modify the name of the bucket at the top of ./scripts/create-s3-bucket.sh
and also update the bucket name in the .env
file (so the lambda knows which bucket to read and write to).
Create the bucket using the following command:
npm run create-s3
and to the .env
file add:
S3_BUCKET='name of bucket'
There are three microservices apart from the GraphQL microservice.
Clone the following repos and run npm run deploy
for each one.
- song-suggester - Queries the Last.fm api to retrieve song suggestions (requires an
API_KEY
as an environment variable) - s3-save - Saves a selected song to an s3 bucket
- s3-get - Retrieves all songs from an s3 bucket
The lambda functions are zipped and uploaded to AWS using the dpl
node module. The components of the function are specified in the files_to_deploy
key in the package.json
. The important file is index.js
which must contain an exports.handler
function which accepts event
and context
parameters. The node modules in the dependencies
in the package.json
are also zipped along with any other files that are specified before being uploaded to AWS Lambda (either updating a function or creating a new function if it doesn't exist).
dpl
names the lambda using the name in the package.json
with the major version number suffixed e.g. 'serverless-graphql-v1'.
Have a look at the notes in the dpl npm module docs or ask @nelsonic for more info!
Then save the following three environment variables to the .env
file in this repo - this will be used by the graphql lambda to call the correct microservice.
LAMBDA_SONG_SUGGESTER=song-suggester-v1
LAMBDA_S3_SAVE=s3-save-v1
LAMBDA_S3_GET=s3-get-v1
Now time to deploy the GraphQL lambda function and connect it to the API endpoint!
To modify the name of the API you can edit the ./scripts/create-api.sh
file. You need to set the name of the lambda function at the top of this file.
Run the following command in your terminal window (which has all the environment variables set)
npm run deploy-app
The aws-cli
is used to create the API Gateway endpoint and link it to the lambda function.
Have a look at the ./scripts/create-api.sh
file for the step by step process.
The last command is a test invocation of the api gateway endpoint to check it has been connected correctly with the lambda. It should print a list of songs which have the name 'Stronger'!
When your API's resources receive requests from a domain other than the API's own domain, you must enable cross-origin resource > sharing (CORS) for selected methods on the resource.
This can be done in the AWS Console.
Navigate to the stages section and select 'prod'. You can then find the api invoke url. This will be needed to set up the GraphQL IDE (GraphiQL) and for the UI to invoke the lambda function
GREAT! Your lambda and api are now ready for the front end!
Head over to https://github.com/nikhilaravi/serverless-graphql-app to learn how to deploy the GraphiQL IDE to query your schema and the UI for the Jukebox app!
There are some example tests in the test folder for the GraphQL schema and services. You can run the tests with
npm test
The coverage isn't 100% yet but i'll be adding more tests soon!!
- Add more notes on the AWS configuration and setting up of credentials and the cli
- Update the 'create-api' script to update the gateway endpoint if it has already been created
- Add a script to Enable CORS from the command line