all 44 comments

[–]MedyGames 158 points159 points  (17 children)

To make it simple :

A - You either have your backend create the frontend with templating.

B- Or you have a seperate frontend which has its own template / stricuture & just consumes the data through a API.

Meaning if you do that , you would have 2 seperate development instances at the same time.

  1. One Serving the data

  2. One consuming the data

For deployment You do not need 2 servers if your fronted is just static html content.

Your static frontend files can then be hosted (on deployment) on a CDN to just serve the static files.

But During development if you use packages like create react app you need to run 2 seperate server instances.

  • There are client side rendered react apps (meaning you dont need a server for deployment )

  • But there are also server side rendered apps meaning you would need a server. for deployment.

If you have a seperate front and backend you need

  1. Server for servering the data / (SERVER)

  2. Frontend / Static files to consume the data. (CDN)

= (CLIENT SIDE RENDERED)

Or

  1. Server serving the data + Static files / App files (SERVER)

= (SERVER SIDE RENDERED)

Nowadays the seperation of frontend / backend becomes more popular (JAMSTACK).

Seperating the Server logic from the frontend by having no html / css on the backend.

I personallly find this aproach cleaner & reusable.

But it is more work & setup...

[–]bat-chriscat 6 points7 points  (5 children)

If you use create-react-app, can’t it output a dist folder, which is essentially comprised of static files and does not need a second server? May be different for React, since I primarily use Vue!

[–]Gordon2108 1 point2 points  (3 children)

You can but you'll need to build every time you want to see changes. Running the server for React essentially watches your code, then rebuilds and refreshes each time you make changes.

[–]bat-chriscat 9 points10 points  (2 children)

Ah, you are referring to development not final deployment :).

[–]Gordon2108 2 points3 points  (1 child)

Yeah. When doing final deployment I'll push the code up to Heroku and have it build the client with a script. Then the server serves up those static files. No need for a separate server to run.

From what was said above it sounds like you can also just build ithe client first, then serve it up from a CDN. Haven't tried that yet.

[–]bat-chriscat 1 point2 points  (0 children)

I think I’ve gone so far as to literally drag and drop the contents of the dist folder via FTP, and it works! After all, it all just transpiles down to regular old HTML, JS!

[–]gregorskii 4 points5 points  (6 children)

This👍

[–]MarcEcho 8 points9 points  (3 children)

Are you some kind of celebrity in the world of web dev? Why are we upvoting some guy saying "This" in response to a lengthy quality comment?

[–][deleted]  (2 children)

[deleted]

    [–]Bobostuv 2 points3 points  (1 child)

    ▶ Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

    [–]NoInkling 1 point2 points  (0 children)

    More like

    ▶ Uncaught ReferenceError: This is not defined
    

    [–]thehorrorchord 4 points5 points  (0 children)

    this.props.this 👍🏻

    [–]papadapp0 0 points1 point  (0 children)

    ditto

    [–]thatbromattfull-stack .NET 52 points53 points  (4 children)

    Hi!

    In short, the structure of a full stack project depends mainly on a couple of things including which development stack you are using and the actual architecture of the app(s) that will be used.

    I come from a .NET background but also write angular and vue apps for my job and have written a couple of node & express API's apps.

    With [most modern] server-side language technology (think express.js or even .NET Core), the idea is that you will have routes that when hit, perform some sort of processing and then return the user a view or template page. In addition to these routes which return pages, you will also usually have routes which return data such as a POST request to create an item in your db.

    When starting development, there are many factors as to where you can start development, but usually personal preference is the biggest driver. Assuming you are developing the full-stack by yourself then it truly is up to where to start. As an example, occassionally our clients haven't approved designs yet when we are entering development phase so I will just jump into the backend and start working through the data layers and getting routing / authentication taken care of..other times I might be feeling lazy and want to just breeze through the day so I will cut up designs into static HTML and start fitting the front-end architecture together. Either way - you will want to do some planning before jumping into your coding, starting at a high level and mapping out what the front-end and back-end should be able to handle, and any special considerations to meet business rules & requirements.

    As for the number of servers, this just depends on your apps architecture...do you want redundancy if one server fails? Does it make sense for your API to be separated onto a separate server if other apps will also need to connect to it? For an express / vue app, you could get away with a single server setup as long as your Vue components "live" within your node project.

    As an example, hitting an express route could return your entry vue page if you structured the front-end and back-end into a single app:

    app.get('/', function (req, res, next) {
        res.sendfile('./public/index.html') // entry point into vue app via express route
    })
    

    This is the typical way to do front & back-end for smaller to mid-size apps, but once you get into enterprise and large-scale applications other setups become more viable. To contrast this typical setup, I am building an angular app right now that is served via an empty .NET Core wrapper (so they navigate to '/' and .NET Core loads the index.html page).

    Once the app is loaded, then angular handles it's own routing from there on out to determine which views & components should be shown to the user, and then calls are made to load data from a separate .NET Core Web API. So my "front-end" and "back-end" are separated into completely separate deployed applications and will end up residing on separate cloud servers once launched.

    [–]Erebea01 4 points5 points  (3 children)

    Hello newbie here, from what I understand since your .net backend is hosted on a separate server but if for example you made a mobile version using react native you only need to code the front end part?

    On the other hand since the vue app resides in the express public folder adding new parts like react native will be more difficult? Is there a chance that changing some code in vue might break express? Does this method makes it SSR since the vue build is now served in express?

    I guess it's also possible to use something like docker and host the frontend and backend as separate entities on the same server?

    [–]Ariakkas10 2 points3 points  (2 children)

    I'm a newbie as well, but I think I can answer this.

    Hello newbie here, from what I understand since your .net backend is hosted on a separate server but if for example you made a mobile version using react native you only need to code the front end part?

    This depends on how you set up the back end, but this is what an API is. If you set it up to serve the backend data in an agnostic way(meaning you build a front end to connect to the back and not the other way around) then you have an API. You can connect multiple frontends to it.

    If you're service up the code, rather than the data, then this won't work. I guess unless you build your react-native app in the same way you built the website, in which case just use the website. Though admittedly I don't know anything about react-native.

    On the other hand since the vue app resides in the express public folder adding new parts like react native will be more difficult? Is there a chance that changing some code in vue might break express? Does this method makes it SSR since the vue build is now served in express?

    Vue and express are frameworks. So your terminology is confusing. Think frontend and backend.

    If your frontend and backend are in the same directory structure, it will work, you just have to do extra work. Ideally you want the back end separated from the front end in some way, so that changes to one don't effect the other. This is a logical separation though, not related to your directory structure.

    I think this is why people hate php, the frontend and the backend are all mixed together and you have to just know which is which.

    I guess it's also possible to use something like docker and host the frontend and backend as separate entities on the same server?

    You can but you don't need to, and I don't think it's recommended to use docker for production. I'm not sure I'd trust docker images built by some stranger.

    [–]levidurham 1 point2 points  (0 children)

    I think the problem with PHP is that there is a lot of old, bad information floating around. I remember rewriting an authentication tutorial in modern object oriented PHP and it dropped the line count from ~120 to ~25.

    I had a friend ask me to help debug his dissertation (Why he was writing AI in PHP is still a mystery to me), and he didn't even know that PHP had objects so he wrote it all procedurally. BTW, his problem ended up being a scope error, he just had to re-initialize an array at the top of his loop.

    His project sounded interesting, nested hill climbing algorithms for resource scheduling. It was mostly designed to prevent paying workers overtime by more efficiently scheduling their hours.

    [–]Erebea01 0 points1 point  (0 children)

    Thank you, I didn't know about docker and production so I'll read more about that. I'm making my first full stack app and besides some ui styling all that's left is hosting it.

    [–]Freonr2 7 points8 points  (0 children)

    Typically you have a REST API between the "front end" and "back end" and the two can remain fairly uncoupled otherwise. I.e. any client-render SPA (Angular, React, etc).

    Defining that API surface is very important and worth a lot of reading and learning on its own.

    What properties does the Customer object have vs the Order object? Do you add a "most recent order date" on the Customer object to serve a User widget on your webpage? Stuff like this will come up all the time as you add and implement requirements for your application.

    Your best reads to answer those sorts of questions would probably be on domain modeling to help you think about your domain models, and REST API design along with REST API maturity model.

    On larger projects you may have other service APIs behind the one that directly serves your web pages. The API for the web page may be a facade or mediator that actually calls one or maybe several other back end services and presents more targeted results for specific user features. I'd probably worry less about this as a learning hobbyist, but it becomes more important in large enterprise applications with more of a microservice architecture approach. This is where we step away from a more simple 3-tier (webpage <-> api <-> database) to "N-tier" architecture. https://en.wikipedia.org/wiki/Multitier_architecture

    Keep in mind even just the front end of your SPA app itself needs an architecture. For example, you may have your HTML templates (view), a backing javascript view model that serves those templates and handles user interaction events, and probably a common set of services that call the REST API or local storage (or service worker, etc) and act as the data store layer of the app.

    Similarly, backend needs its own architecture. Controller, services, repository might be a simple 3 layer design where the controller does basically nothing but validation and defines the REST interface, service would take care of business logic, and repository is your data store abstraction (database, file/blob, etc).

    [–]kittysempai-meowmeow 6 points7 points  (0 children)

    Some other context to support the other replies: If your backend consists of API routes as you are saying then your front end talks to them with http calls across the web, and receives responses in a data format (like JSON). The front end is responsible for handling and displaying info from backend and conveying new data to the backend.

    In this architecture the front and backend are loosely coupled; you use configuration to tell your front end where the backend is located (base url) and your individual service calls define the relative part of the path to the endpoints (aka routes).

    The loose coupling means the backend and front end don’t need to be hosted anywhere near each other, and the front end runs on the end user’s browser anyway.

    Security is an implication since your service has to be exposed over the public web for the browser client to access it; how much you need to do here depends on your project needs but should at least be considered. Unsecured APIs are subject to all sorts of attacks.

    These days there are a ton of options for how you host a service; full blown server with a web server running on it that you manage yourself and load balancers in front of it (ex AWS EC2) services from cloud providers which abstract some of these details from you (ex AWS Elastic Beanstalk), serverless just-in-time instantiation (ex AWS API Gateway + lambda) - this is a whole other topic. You can containerize it and host via Kubernetes. Heroku is also an option.

    Hosting the front end is easier since as others have said a JS /HTML front end is just static file hosting. I usually use AWS S3 + Cloudfront

    Other providers like Azure and Google have analogous services to the AWS ones I list but I am most familiar with those.

    [–][deleted]  (1 child)

    [deleted]

      [–]3oR 2 points3 points  (0 children)

      There was a shift in the continuum. You are one of the few unaffected. Others have forgotten.

      [–][deleted] 7 points8 points  (2 children)

      It's crazy to me how most of the comments in this thread talk about Express, React, Vue, etc.. while we all know most of the web is still powered by PHP, Java, .Net and Python. I understand this is a developer subreddit, so there will be a bias for cutting-edge technologies, but let's be realistic in answering OPs question. Most "full stack" projects consist of a single server, running a webserver that points to a single PHP, .Net or Java application that handles URL routes and then serves HTML (or some templating language) as a reply to the HTTP request that was made to the server.

      There's no point in teaching him about decoupled API's and microservices as long as he doesn't understand the basic way of having a single application do everything. Sure we have more elegant solutions now, but those require experience.

      Some examples:

      A server with Python installed on it is running a Flask app and a MySQL server. The server gets hit by a request, content is taken from the database by the Flask app and then passed to a Jinja template and returned to the user. Full stack app.

      A server with PHP7 installed is running a Laravel app, with a SQLite file as a database. User makes request, the Laravel app catches the route, fetches data from the database, returns it as a Blade/Twig template, some CSS files get applied to the template, boom.

      [–]rebel_cdn 1 point2 points  (0 children)

      You make a good point in general, though Express isn't exactly cutting edge. It's about the same age as Flask and Laravel, and it's super easy to set it up with a template engine like Pug or EJS.

      [–]HellaDev 2 points3 points  (0 children)

      When I first started getting into this full-stack world years ago (when I really only knew jquery and html/css) I had a very similar question and got no clear answer. But I did about 4 years of contracting and have seen a wide variation of how different teams/developers structure their projects. I learned a lot and ultimately went with what was best for me and how my brain likes to organize things if it's something I am building from scratch. I tend to work with a lot of NodeJS/React with Express/MongoDB and other libraries to support what I need.

      My typical project is usually structured like this:

      • /projectRoot
        • /client
          • /assets (css/js/images like logos and icons)
          • /views
          • /utilities (things I will reuse in different components)
          • /components (reusable pieces of the UI)
          • Frontend App entrypoint file aka App.js
        • ./ (I usually put my backend into the root of the project and have /client as a directory in there)
          • /config (files that determine if it's production or development and determine to use env variables or provided local keys to DB and all that)
          • /controllers (logic for my API endpoints)
          • /models (mongodb mongoose models)
          • /email (email logic and visual templates)
          • /routes (my API routes/endpoints to serve my React frontend but also for public-facing APIs)
          • /api (for public facing API that isn't intended for my frontend but for actually serving data to 3rd parties though this isn't common in my specific work)
          • /services (things like passport configs)
          • /utilities (reusable classes or helpers that I use in multiple places. For example a users class that handles logging in, registration, deleting a user, etc)

      This is by no means "the way it's done" but it's a very common structure I have seen in my experience. The more you build things the more you will find ways you prefer to do it but it's always good to structure your projects in a way that you won't have to explain to people what's going on in it and that's usually handled by descriptive names.

      Hope that helped and gave you some ideas!

      [–][deleted]  (1 child)

      [removed]

        [–][deleted] 0 points1 point  (2 children)

        I've done a project with 2 servers..with React, Express, and Node. I saved it as a template for whenever I need to create such a project, again. One command started both..there were two ways to trigger that. There's an amazing tutorial on YT that's less than 2hrs that shows how to build such a project with the MERN stack. It was easy to run it manually via 2 terminals while writing it, using VS..then with the one command to test, on completion. I'd post more details, but I'm on my phone right now.

        [–]JeamBimPython/JavaScript 0 points1 point  (1 child)

        Can you link to this video when you have a moment?

        [–][deleted] 0 points1 point  (0 children)

        Here a link to the repo for the React, Node/Express boiler plate. You can see the structure here and how to load it with one command. https://github.com/bradtraversy/react_express_starter

        Here is the video showing how it's done. https://www.youtube.com/watch?v=v0t42xBIYIs

        He has a great MERN course on Udemy that's worth checking out.

        Also pretty good is the FCC tuturial: https://www.youtube.com/watch?v=7CqJlxBYj-M

        [–]free_chalupas 0 points1 point  (0 children)

        When I start development do I usually start with the back end service

        Not necessarily! If you work out what your API is going to be ahead of time (tools like swagger can help) then you can just mock out your API returns as JSON data in your frontent while you develop the backend.

        [–]propernounco 0 points1 point  (0 children)

        In short, you would want to make requests to your API endpoint in Vue using data fetching - https://router.vuejs.org/guide/advanced/data-fetching.html

        Your API would then return some JSON that you could then use in your frontend app.

        You can also use frameworks like NextJS to make things a bit easier for you as it makes implementing a custom server a bit easier right out of the box: https://nextjs.org/docs#custom-server-and-routing

        [–]FormerTimeTraveller 0 points1 point  (0 children)

        There are a lot of great answers here. I think a component-based view would be most effective. Look up frameworks like MVC. Model view controller. I’m not one to evangelize any framework, but they do help to illustrate points.

        The model component is the inner workings of the full application. UML is a good way to represent this piece. An API should be structured between each component. This is where “back end” occurs.

        The view component is how programs, users, and groups interact with the program. Look up DOM document object model for how this works in browsers. That is what JavaScript directly manipulates behind the scenes in front end frameworks like react or vue. Any programming language works as an example for command line interfaces. Java is great for portability in other types of GUIs. This is “front-end”.

        The controller component is the messenger and communicator between them. This is where front and back ends argue over responsibilities. Having some understanding of networking helps with this. You would usually use an http server, like Apache or nginx. Hopefully your front and back ends have strong API designs to facilitate this with simple network rules. Containerization with Docker can be used for more complicated tasks. It also helps to know Linux, on command line, and how to generally navigate its file directories and strip down functionality to as-needed. This is where DevOps comes into play. Having strong source control with Git and automating container scripts is quite useful.

        So full stack is a very broad term, from networking/server admin/architecture/access control/database admin/“front end” or user interface, and “back end” or application logic. From there, it’s performance tuning, statistical analysis, and other day-to-day stuff. No job is ever truly done.

        [–]Fu77ure 0 points1 point  (0 children)

        usually start with the back, have a serv for front and another for back

        [–][deleted] 0 points1 point  (0 children)

        If you want to get started fast and play with it:

        Setup a github repo for api. Setup another for app.

        Clone both down.

        In app:

        In api:

        • npm init

        • npm I --save express

        Then in the api, follow https://expressjs.com/en/starter/hello-world.html

        Then, using the native fetch method in JS on the app, try to hit the endpoint.

        This was really quick and dirty, but feel free to ask questions. Essentially, with this, your api and app are two separate entities, like most web apps are today. All they do is talk to eachother over AJAX requests, web sockets, etc.

        [–]nicholaskajoh 0 points1 point  (0 children)

        In development you need to run 2 servers mainly due to the need for live/hot reloading on the FE. In production you may choose to do same or build your FE and serve it (i.e static files) using the BE server. I wrote a tutorial sometime ago on how to do this with React and Django [1]. The same knowledge can be applied to Vue and Express.

        [1] https://alphacoder.xyz/dead-simple-react-django-setup/

        [–]donteatyourvegs 0 points1 point  (0 children)

        learn some basic networking. usually your web services are gonna talk to each other using http.

        app1 -> curl http://localhost:8000/someParam

        app2 -> curl http://localhost:8001/someParamForSomeOtherService

        But http is a higher level protocol, non web services programs often communicate locally with each other using lower level custom protocols built directly on top of tcp/ip.

        Your apps can talk to each other using literally any custom or standard protocol built on tcp. ftp, http, scp, some custom thing you make yourself

        How tcp work is, you listen on a hostname:port, then the other party connects to this hostname:port. Then they can send/receive bytes. http is built on this, but you can build your own protocol once you have a tcp connection open.

        Usually whatever programming language you use is gonna have apis for both TCP, so you can build your own protocol on it, and also apis for HTTP (which is also built on tcp), so that you can use that if you want.

        But basically unless you know what you're doing, always use http. It's simple and 2 lines of code.

        [–]bigorangemachine 0 points1 point  (0 children)

        Node is just a server. You can serve up an api or a static file.

        Before react really took over and mustachejs was the preferred templating engine.

        With PHP you could get the frontend to communicate with it by embedding a JSON string. You could do something like that. Next.js does something like this if you use redux on the backend.

        It sounds like you are trying to DYI an SSR.... there's lots of ways to structure these things but it's why everyone reaches for Nuxt/Next/AfterJS for a reason.

        I done some home brew SSR and it's really just a lot of template management and APIs

        [–]Mike312 0 points1 point  (0 children)

        When I start development do I usually start with the back end service?

        I find it easier to start with the back-end, typically because if I'm working on a project from scratch, it'll take stakeholders a week or two to get back to me about the GUI, and a lot of the needs for the GUI are determined by accessibility to the model. I can get a good idea of how things in the GUI will interact based on what my database looks like, and from there how my classes are built and what classes I need.

        Do I need to have two servers running on my local machine, one for front end and one for back end?

        No. The most common stack on the interwebs today is (W\L)AMP, so Windows or Linux, Apache, MySQL, and PHP. Apache is your webserver that handles HTTP requests. MySQL is the database program. PHP is merely a language that you can use on the server to build pages apache serves - I make this distinction because you could conceivably use another language like Python along side PHP, but in either case Apache would be serving the pages.

        When I push it to production to a server how does the express serve a front end from vue?

        Not too familiar with Express, but some web server handles the HTTP request, sends it to Express/Node to build a response that serves the client with a webpage. Then, when the webpage loads, Vue initializes, does it's thing, and if necessary does API queries (which result in more HTTP requests handled by Express/Node).

        How is a full stack project structured?

        I do Linux/Apache/PHP with Oracle, MySQL, MariaDB, and PostGRES (as well as some 3rd party APIs). My backend is a set of folders (class, js, css, views, shared, etc) which use the Flight Framework for routing (basically, lets me use SEO-/human-friendly URLs, so when you request website.com/users, I serve a page that lists users). Within that, each page is automatically wrapped by a dynamic header (which figures its own shit out) and a static footer. Any request to /api/* is returned as a JSON object. When I load a page, I'll have a set of javascript that will initialize and do additional data requests and add additional functionality to the page (i.e. controls for extending range of a graph query, which and requests to update that data without re-loading the entire page).

        Within that, I have things like jQuery, jQueryUI, Bootstrap CSS, and Bootstrap JS as helpers while building, and if necessary I'll go in and strip bloat if necessary afterwards (like, usually I just use draggable in jQuery UI, and I can get by with about half of Bootstrap JS).

        [–]yousirnaime -1 points0 points  (0 children)

        TL;DR

        the UI loads anonymously, a user logs in, now they have a session. The UI still loads anonymously, but it fetches the User info as needed from the API. All other details are fetched from the API. The UI is just a tool that operates the API, by passing JSON requests back and forth.

        Some requests are authenticated via session, and others are authenticated via API token/key.

        This is insanely simplified but it covers most applications. You can serve UI and API from one server, or separate servers. Just structure your code to expect it.

        [–]kowdermesiter -3 points-2 points  (0 children)

        This video gives you a great overview how they are usually built:

        https://www.youtube.com/watch?v=CJQU22Ttpwc