There are two camps within our ranks: the first camp believes the front- and back-end should be completely separated, where both applications have separate version control, build processes, and deployments.
Disclaimer: I'm in the camp that believes strongly in separating the two. So I want to argue the case for separating front- and back-end completely in the post.
HistoryIn ye old days there was only one way to create a website: Using a text-editor you started writing HTML, and when you were done, you uploaded it to a web server. The HTML was static and every time something needed to change you edited the HTML file, and uploaded it again. Easy peasy.
Smart programmers thought: "if we can generated the HTML dynamically, we can do way more cool stuff with the web." Thus was the back-end created and programmers rejoiced. You picked a language and a database and off you’d go. We didn't create websites anymore but web applications.
A funny thing happened to HTML and CSS along the way. They seemed to become less important to web development, almost a necessary evil to make things work. Take job descriptions from this period: Big bold letters: "Looking for Java developer" somewhere at the bottom in a list in a way smaller font: "Knowledge of HTML and CSS are a plus".
We saw HTML and CSS as a thing to be generated but not the actual application. The actual application was written in Java, PHP or C# the HTML was just a build artifact waiting to be served. Heck, some platforms such as "ASP.NET Web Forms" went out of their way to hide any sort of HTML from the developer.
I remember seeing 'Ajax' for the first time on Gmail, it was loading new emails whilst the page was kept open. I didn't believe my eyes, I was sure I was seeing things. I checked my computer to see if I had installed some Google application that refreshed my browser somehow, or that I installed some plugin.
Then the iPhone happened and later Android. Suddenly we found ourselves in need of writing APIs to provide these apps with the same data and CRUD functionality our traditional web apps needed. Since our web apps didn't use Ajax for everything, we started writing REST APIs next to our traditional endpoints. Effectively writing some functionality twice.
But what if the 'MVC' front-end would also only use the RESTFul back-end like the iOS and Android apps already did? Then all 'apps' use the exact same calls, and the web apps would no longer be a 'special' case. REST calls returning JSON all the way down.
The front-end part of the equation has finally come onto its own, no longer needing a special 'relationship' with the language the back-end side was programmed in.
Now that the history is out of the way I'll start making my case.
Separation of ConcernsWhen I came to work at 42 my first assignment was assisting on a Java project that needed to provide a RESTful interface for an iOS app. The project already had a web based front-end, the idea was that the iOS app would eventually support all features the web app did.
The web app front-end used JSP with some jQuery to make it more dynamic. Not every functionality used Ajax, but most did, so another goal of the project was to use Ajax for everything and gut JSP from the project. This way the web app and the iOS app became equals using the exact same API.
We went from a project that had its front- and back-end interwoven, to one where the two only communicated only via Ajax calls. The back-end's job was to provide data, expose ways to manipulate it, and to secure access to the data. Its last job was to serve the HTML for the web app.
When we were done I looked at the relationship between the front- and back-end. The only concrete relationship the two had was that the back-end served the front-end. If I had ripped out the HTML from the project, had it served by another server under the same domain, the Java back-end and even the end user would be none the wiser, everything would still work as before.
Looking at the relationship between the iOS app and the web app I realized they were brothers, they were familiar. Both used the back-end in the same way to authenticate a user and send the same HTTP GET and POST request to get things done.
I realized something: When the back-end and front-end only communicate with each other, but don't need each other, they are separate entities.
From the perspective of the back-end all I need to do is send valid HTTP requests. I can use the entire application from cURL if I want to. The back-end simply doesn't care as long as I send valid HTTP requests in the correct format. The back-end is completely unaware on what consumes its service.
The front-end has the same perspective, it calls some service at some URL. As long as the response is valid, and the service does as promised, the front-end doesn't care what the back-end is. If it's written in Java, PHP or Ruby it doesn't matter, heck, even a monkey sitting behind a keyboard would work as long as the communication works via the same protocol.
The front-end, whether it’s an iOS app or web app, is a separate entity from the back-end. They are separate concerns.
Version ControlIn the project described above, the web app and the back-end shared the same version control repository. The iOS app had its own repository.
On one hand there was the history of the back-end: "changed HTTP call", "Optimised login and made it faster". The other commits were front-end: "Moved navigation to top of screen", "Increased the size of the font".
These commits were often interwoven, worse yet some front-end changes were considered too 'minor', so they got packed together with 'back-end' changes.
When looking at the history from a back-end perspective, the commits looked littered with stupid minor stuff some 'front-end' hipster frontender made. Ruining the view of the API.
When looking from the eyes of the front-ender, the exalted commits to enrich the users experience were interspersed with commits from a neckbeard ranting on and on about "REST" and "HTTP" and "optimizing". Whatever that meant. It made looking how the UI changed between versions more difficult.
What does a background color of a website has to do with an optimization in the login routine? Nothing.
I also thought about my changes to the front-end and back-end. What if only the changes to the front-end needed to be reversed, that would be very uncomfortable since the history is so interwoven.
When you are in control of your own tooling it becomes easier to extend them and you can use them everywhere. Gone are the days of switching between a build processes for an AngularJS app when switching from a Ruby back-end to and a Java back-end.
So all you need is a web server that is good at serving static files. Which is easy because serving static resources means you can cache the app more easily.
Plus knowing that an application is static means you can use content delivery networks to serve the application more easily.
Via Grunt it is possible to generate a package that has made unique names for each resource, such as images, CSS and HTML, and which is ready for deployment. Updating the app becomes as simple as uploading a folder.
CulturalSuggesting moving the front-end and back-end into their own repositories, and stopping to serve the front-end from the back-end invokes some negative responses:
"Why put them in separate repositories, I'm a fullstack engineer I do both front- and back-end work. It will just make my life harder."
"It's so convenient to have to deploy only one package."
"Maven can do that too, all you need to do is (some magic that a non Java enabled front-ender cannot possibly understand)."
I think it is a "culture" thing. Once we start seeing web apps as mature applications with their own build processes, conventions and culture, it becomes more natural to separate them from the back-end.
Here's a thought experiment: You're a developer making a web application via AngularJS calling a REST service you've created with Spring MVC. Suddenly a wild Pointy-Haired Boss appears with an iOS developer in tow, he's going to make the iOS version of the application.
Would you include the Objective-C and Swift code in your git repository?
Would you configure Maven to kick-off a Mac-mini to start the iOS build process, every time you add change something on the server?
Would you like to be emailed when the iOS programmer makes mistakes when the build has failed?
Would you mind it if the iOS programmers mistakes send you emails that the build has failed?
Would you change your release task to submit a version to the App Store?
Would you hold your release until it has completed the App Store approval process?
Did you vomit a little bit just thinking about these unholy questions?
ConclusionSeparating the front- and back-end into their own repositories makes it easier to revert changes.
Deploying static files is what servers are good at, using Grunt it becomes really easy to generate these static files.