Dynamic Website using AWS - node.js

I want to host a dynamic website using AWS serverless. I plan to use Lambda, API Gateway, DynamoDB and S3. My frontend pages will reside in S3. The blocker is that there would be some dynamic items such as Usernames and other metadata which will be user-specific. I know so far that the best we can do is pull the html page from S3. How do I then go ahead and include these variables in those pages?
I would be writing lambda in NodeJS.

Your HTML (static page) should have all the input fields (in your case user name and meta data). You can use any clide side javascript library to take values from those input fields. Even you can use classic JavaScript (like document.getElementById ) to take values from input fields but that will be the pretty old way of doing even if it works.Once you take the needed values then you can compose Json out of that to call lambda function via API gateway. Though S3 supports only static web site hosting you can write JavaScript code inside your HTML, which will not consider as dynamic (like C#, Java etc. ).
Big story short you can acheive anything through JavaScript in the static page you hosted in S3 and compose proper Json in the way your Api gateway / Lambda expecting.

What you mentioned as blocker for dynamic items such as usernames and other metadata. You can use AngularJS or other Framework to handle dynamic variable in application.
You can also use AWS Cognito for authentication.

For a serverless website like you describe you need to make the distinction between the static, and the dynamic content.
The static content, like HTML pages, Javascript files, CSS can be hosted in an S3 bucket.
For dynamic items you can use Javascript or any JS framework, and use it to interact with a couple of lambda's that return dynamic data.
These lambdas can be attached to an API gateway.
If you want to store- and retrieve data to a database you can use DynamoDB, or an RDS instance, that way you don't need to manage any servers
If it is just about authentication you can use AWS Cognito.

AWS S3 is fine for the front with angular for exemple.
For api I use nodejs in docker container in Aws ECS.

Related

How to create mock for AWS resources like dynamoDB for local development in nodejs lambda?

Does anyone know how can I mock AWS resources and their operations for local development? Currently I have a lambda that inserts values into dynamoDB. I'm not looking for test case purpose (will need these later on), but if possible I can do these operations without calling actual services?
Currently I have created a mockdb.js file with similar values of dynamoDB but to run the code everytime on my machine, I have to comment out the actual aws code and mention-
import {data} from '../mockdb.js';
const list = insertTable(data) // everytime I have to add this instead of aws dynamoDB sdk
Is their a easier way? Eg. For react applications we have mockservers to mimic route responses?
There is no easy way to test and develop all AWS services locally but there are some solutions which cover some services and use cases (the list is not exhaustive):
Localstack: https://github.com/localstack/localstack
SAM framework allows local testing and developing for some services (Lambdas and API Gateway): https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-test-and-debug.html
There is a downloadable local version for DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
For missing services you have to develop your own mock services/functions and use them for developing testing.

Storing assets within the AWS ecosystem

I am newbie to AWS development (but have extensive experience on traditional development).
I need to build a web app with ReactJS frontend, NodeJs/Express backend, MySQL. Its SaaS app possibly with thousands of clients. There will be a use case where we have a Parent client having hundreds of Child clients.
So, parent-child relationship within clients itself. Child's settings supersede parents. Each client (doesn't matter child or parent) will have its unique logo and style. Child may or may not override logos and styles. If Child doesn't override it gets from Parent Client. and so on..
I can handle logos/styles/settings at the time of client's onboarding using some configuration tool. Thus, I will upload/change the logos/styles/settings for parent and/or child clients- at the time of client's implementation. I need ability to change these logos/styles/settings, later, whenever clients demand so.
What are my options on how to design the app: (again, I am newbie to AWS)?
Storage-wise, what's the best place to store logos/styles/settings? If AWS S3, will it provide me certain folder layout to handle parent-child or should I dump all images/styles(css) in single folder with client's prefix on each item?
Other option, pulling of images/styles/settings during runtime when site renders. Thus, I will to determine parent-child relationships for every click on web app and determine where to grab the resources from. Little overhead at runtime since I am pushing the parent-child logic at runtime instead of configuration-time/one-time.
Any thoughts/alternate design/suggestions/pros&cons with respect to AWS environment?
Assets are definitely best place in Amazon S3, each asset is referred to as an object within Amazon S3. You give the object a key such as client/main.css. By doing this you could separate out each client into their own prefix (you might see this to look like a subfolder within the GUI).
With setting it depends how sensitive they are, if it is simply for your frontend then you could store a JSON file in S3 within the same prefix as your assets. Otherwise if there should be some security over the settings you can use DynamoDB which boasts "DynamoDB offers consistent single-digit millisecond latency".
As Chris Williams has already mentioned, use S3 as your raw data store for images, js, css, html, other assets. Additionally, you can set up a cloudfront distribution in front of these assets to serve them quickly to your customers. Cloudfront has edge support as well so your website will be performant globally.
Theres a lot of great resources on S3 + Cloudfront for website content serving available online.

AWS S3 Standard upload scheme vs Browser-based uploads in node

I'm trying to understand what are the implementation differences between a standard AWS S3 upload scheme (e.g. using aws-sdk) and browser-based uploads, particularly, in node.js.
I understand that in any case, there needs to be a server that will store my AWS credentials and sign the requests to S3.
But there's a bunch of things I don't seem to understand:
If I use a browser-based upload, I'll have an HTML form on the client side with the signature and the policy values in hidden fields that I get from my server. But if I use a standard scheme for uploading files, i.e. completely through my server, how exactly is it implemented? There's a lot of code examples on server side implementations, but what should happen on the client side? So, there will be an HTML form with action attribute pointing to my server's URL designated for file uploads, right? But what will actually happen? Will the file firstly get uploaded to my server's storage and then to S3? Or will it somehow use streaming or something? It really confuses me and I'd really appreciate some code example where there's both server and client side code.
What are the pros and cons of both uploading schemes? When should I favour one approach over another (my personal use case - video uploads in a multi-account system)?

JavaScript REST-API file upload security/ACL

I have a HTML5 static site and use Parse as the back end through REST API.
So my application id and REST API key are completely open to the public.
My classes have ACL so it should be relatively OK. But I also upload files to https://api.parse.com/1/files/ using JavaScript through REST-API .
How can I allow that only logged in users can upload files? Unlike normal classes on which I can set class wide ACL, anyone can upload files to my parsing application.
First off I would ask why you are using the REST API instead of the native JavaScript API... the JavaScript API uses the REST API under the covers, it just adds a nicer layer of interaction to work with.
Anyway, that aside you can't stop people from uploading files unfortunately. You can stop them from assigning those files to records via ACLs though, and you can do a cleanup on files that are not linked to objects.

Serve custom javascript to browser via Node.js app

I developed a small node.js app in which I can configure conditions for a custom javascript file, which can be embedded in a webpage, and which modifies the DOM of that page in the browser on load. The configuration values are stored in MongoDB. (For sake of argument: add class "A" to DOM element with ID "B" )
I have difficulties to figure out the best way to serve requests / the JavaScript file.
Option 1 and my current implementation is:
I save a configuration in the node app and a distinct JavaScript
file is created for that configuration.
The page references that file which is hosted and served by the server.
Option 2 and where I think I want and should go is:
I saves a configuration (mongodb) NO JavaScript file is created Pages
a generic JavaScript link (for instance: api.service.com/javascript.js)
Node.js / Express app processes the request, and
returns a custom JavaScript (file?) with the correct values as saved in mongodb for that configuration
Now, while I believe this is the right way to go about it, I am unsure HOW to go about it. Any ideas and advise are very welcome!
Ps: For instance I wonder how best to authenticate or identify the origin, user and requested configuration. Shall I do this like: api.service.com/javascript.js&id="userID" - is that good practice?
Why not serve up a generic Javascript file which can take a customized json object (directly from mongodb) and apply the necessary actions? You can include the json data on the page if you really need to have everything embedded, but breaking up configuration and code is the most maintainable approach.

Resources