We set up a new Next.js project using Create Next App,
and added Tailwind CSS for styling.
Now, before we go on and start implementing
the actual functionality
I want to think about how our application
is going to work at a high level.
A good place to start is from the data.
What sort of data will we need
to build our Shop website?
Well, we'll obviously need some "Products".
That's what we want to sell on our website,
so we'll need the details of every product,
like their name, description, price, and so on.
After that, if we want to sell a product
we need somebody to buy it,
and that somebody will be our "Users",
or customers.
We'll need to save some user details
in order to let people log in to our website,
know where to deliver their purchase, and so on.
Also, when a user selects a product they want to buy
we probably want to save that in a "Shopping Cart".
So that's another piece of information
required by our application,
and it's related to the other two items,
because a Shopping Cart basically contains
Products selected by a User.
This means that whatever mechanism
we choose for storing our data
should make it easy to manage
these relationships.
There are other types of data we may want,
like orders and payments
but for this example let's say
we don't need to worry about those things.
Let's assume that we'll integrate with
some third party platform
that will take care of all
the order and payment functionality.
Now, having identified what kind of data we need
let's think about where we can store it.
We already used some data in our first example,
that was a Blog website.
In that case we used a simple architecture like this:
the data was stored in the local file system,
in the form of Markdown files
containing each blog post,
and our Next.js app was loading the data
simply by reading those files.
Could we use the same approach
for our Shop application?
You can probably guess that
this architecture is a bit too simplistic
for an online Shop.
If we need to modify a local file
every time a new user registers to our website
or they add an item to their shopping cart,
that just doesn't scale.
So instead of the file system
we could use a database.
This could be a relational database,
like MySQL or PostgreSQL
or maybe a so-called NoSQL database like MongoDB.
But in any case, there are many
solid scalable databases available
that are designed precisely to handle
large amounts of data
and also enforce the relationships between the data,
like make sure that a shopping cart
belongs to a certain user.
So this is a possible approach,
we could have our Next.js app connect to a database
using whatever protocol and driver
is available for the specific database we choose.
Now, this may work fine in simple cases,
but rather than having the Next.js app
talk directly to the database
we may want to introduce a middle tier,
a backend application
that is responsible for talking to the database
and exposing the data as a Web API,
like a REST API.
This way our Next.js app can interact
only with this backend API,
typically by making HTTP requests.
The Next.js app is just the frontend;
it doesn't need to worry
about what database is used by the backend.
All it needs to know is how to call the API.
The advantage of this approach is that
this way the Backend API can be used
not just by our Next.js app
but possibly by other clients as well.
For example at some point
we may want to provide mobile apps
so our users can easily shop with us
using their phones.
And those mobile apps could call
the same Backend API as our Next.js web app.
Even if we don't have other frontends to begin with
it may still be worth keeping the backend separate.
Now, we could write this backend application,
for example using Node.js and Express,
or any other framework or language for that matters,
But there are also solutions
that can give us a backend API with little effort.
In particular, we could use a "Headless CMS".
CMS stands for "Content Management System",
and "headless" means we can use it
without a graphical interface.
In other words, a headless CMS provides a web API
that we can call from our Next.js app.
An API that returns the content stored in the CMS,
so that we can then display it on our frontend.
But a CMS typically also provides an "Admin UI",
a user interface where administrators
can manage the content.
For example for our shop, they could use this UI
to add and update the product details.
This means that in our Next.js app
we just need to provide a "Public UI",
that is the website visible to end customers.
We don't need to worry about writing an interface
to let the shop staff add new products and the like,
they can use the CMS for that.
So, this is the approach we're going to take
for our Next Shop.
I'm not going to claim that this
is always the best approach of course.
For any project you need to think about
the specific requirements,
and choose the best solution
for that particular application.
But I would say that this architecture
based on a Headless CMS
is a pretty good choice in many cases,
and in fact it has grown in popularity recently.
Ok. So we're going to use a headless CMS.
Now, the question is: which one exactly?
Next.js provides examples
for many different Content Management Systems.
DatoCMS, TakeShape, Sanity, Prismic, and so on.
These are all headless CMSes.
There more than a dozen just on this page,
and probably some more that are not listed here.
Now, most of these are hosted solutions,
where you sign up online, and all your data
is stored in the cloud.
You can do a little bit of research
if you want to choose a CMS for your own projects.
But the one we're going to use for our Shop example
is Strapi.
I selected this one because
it's an open source project.
It's not a proprietary solution
hosted in the cloud like most other CMSes.
You can download Strapi
and run it on your own machine if you like.
We'll look at Strapi in more details
in the next video.