Modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.
This is a proof of concept, design and solutions are just far enough to see if the approach could work.
👉 Try it out on https://jamstack-static-generated-app.netlify.com/!
- Realize a simple search based application
- The app has private and public areas
- The used tools and frameworks are reliable enough for a global scale project
- One solution for the web application AND marketing pages
- Marketing content and text can be changed without the help of an engineer (CMS)
- Serverless infrastructure as long as possible
- SEO is great (sitemap.xml, web crawler friendly, meta tags, ...)
- Loading- and runtime-performance is great
- Accessibility is great
- React as a basis for a stable web application
- Babel for ECMAScript 2015+ syntax
- jest for unit tests
- ESLint to detect errors in advance and for strict code styles
- GatsbyJS to generate static pages which load quickly and can be indexed easily for SEO
- Netlify for automatic deploys and continuous integration
- Netlify CMS for editing the (marketing-)content, stores the data in your git-repository
- Netlify Identity service as simple authentication as a service
- GraphQL for an extendible API following reliable standards
- Netlify Functions to deploy serverless lambda functions
- Node.js as the language for the lambda functions
- The database is faked up to now
- React
- improved dramatically with the newly introduced Hooks. Code gets easier to read and can be organized modular and reusable.
- Angular with Angular Universal could be an alternative and needs further investigation
- Babel
- the current version supports TypeScript which could be a good improvement
- jest
- offers great features, e.g. snapshot testing
- tests are a "must have" right from the beginning
- they help during development
- it is a pain to write for the existing code you do not plan to change
- automated tests are absolutely necessary for a stable product
- pull requests with failed texts must not be merged to master
- ESLint
- is interchangeable with other linting frameworks
- the rule set for linting is up to the team, but it must be consistent
- GatsbyJS
- has a steep learning curve if you are not familiar with GraphQL but it works perfectly as soon as you overcome this hurdle
- works best if you can query your data from a GraphQL service
- works best if you have regular update cycles for new information (e. g. daily)
- you could overcome this limitation by updating the data after loading the page and/or adding client routes for missing static pages. But this complicates things a lot.
- if this limitation is not acceptable the next step would be server-side rendering instead of generating static pages (e. g. with Next.js), which makes server infrastructure much more complicated and introduces the danger of server-side runtime errors during rendering.
- Netlify
- works like a charm for building and deploying static content
- the tight connection with GitHub allows preview builds and running tests and linters before merging a pull request
- switching to other tools is possible anytime
- the same tasks could be done with a CI/CD tool like AWS Code Pipeline, Azure Pipelines or CodeShip in combination with a storage solution like Amazon S3 or Azure CDN
- e.g. here is a tutorial accomplishing the same on Azure
- as setup and maintenance is easier with Netlify I would stick with it as long as there is no need for more features
- the service is a cost factor
- Netlify CMS
- is a static page including an npm package directly on your server
- stores the contents as markdown files in your git repository
- offers a lot of possibilities to be extended and modified
- is open source
- the dependencies to Netlify services are Identity and Git Gateway . Both are optional and can be replaced with other solutions easily.
- switching to another solution is possible as the contents are not hidden in a database
- Netlify Identity service
- the easiest to use identity service I tried out yet
- uses new standards like Json Web Tokens
- not sure if it fulfills all requirements for a large scale app, but I like the idea to have a stand-alone identity server instead of being tightly tied to other parts of the application.
- switching to another solution and migrating lots of existing users could be really hard, this decision must be stable before going live
- the service is a cost factor
- GraphQL
- after developing so many self-made APIs this deep dive into GraphQL was mind blowing
- there is almost no situation I can think of which does not have a solid solution with that specification
- the overhead when initially creating the Schema pays off as soon as you want to extend the functionality
- I used the light-weight client-side library urql which worked fine up to now and is easily exchangeable
- I only used the GraphQL.js reference implementation and Apollo Server Lambda on the server side
- PostGrahile as the connector to a PostgreSQL database sounds like a very interesting option
- functions as a service via Netlify Functions
- lambda functions are great as you do not need to take care for a server
- there is no shared state between two calls, you will have to store/read from a database if you need it
- in this project, it is problematic to have only one deployment process for the serverless functions and the web application as the build process needs access to the API
- I would recommend using a platform-independent framework like Serverless to be independent of a specific service provider
- there are endless alternative providers, e.g. AWS Lambda, Google Cloud Functions, Azure Functions
- the service is a cost factor
- lambda functions are great as you do not need to take care for a server
- Node.js
- limitations like lack of multi-threading are not relevant for lambda functions as each of them is invoked in its own process
- it is just comfortable to write server- and clientside code in the same language
- there are great libraries for GraphQL available for Node.js
- build a similar project with Angular using Angular Universal
- I am still not sure if it is possible to serve the build as static pages or if it is only possible to run it on a node server for server-side rendering
- build a similar project with vue using nuxt
- I would not use this combination for a big project as React and Angular are much more mature