A lot goes into building a web application, that much is obvious. But what exactly does that process look like? Well, it's time we give you a peek into what it takes to plan and build a solid, reliable, and most importantly scalable web application. We're going to be going over the process for a very specific kind of web application, one that we can also turn into a mobile application.
This means having all of the application's data, like user information, for example, will be stored in a different spot than the visual half (or front-end) of the application, which will retrieve the data through an API (application-programming-interface) that will do all of the database-level communication.
In this example, we're going to plan out a simple task manager. Users will be able to log in, create tasks for them to complete, and then mark those tasks as finished. Super basic, but it'll be enough to make sure we cover all the basics. Also, you'll want to make sure you're properly equipped with the essential web development tools.
First things first, you want to separate the application into multiple parts so you can attack things piece by piece. As I mentioned before, we're going to split the application into two halves. One half will be the API, which will consist of the database schema and the code that will talk to it. The other half will be the part the user sees and uses to interact with. We'll start with the back-end, which should always be where you start. It's also going to take the longest to flesh out, so grab some coffee and hunker down for a nerdy read.
So we'll be using MySQL for this, which is a relational database. We've discussed relational databases before, so we won't get into the specifics here. Rather than explaining what that is, I'm just going to show you by example. So let's look at some functionality and determine what tables we'll need. Well, we only really have two 'things' in this project, users and tasks. Okay, so let's think through what we need for our Users table.
So let's go over a few 'standard practice' items here, and some recommendations. First off, we could probably combine Username and Email, since it's pretty common for people to sign in with their email address. So that leaves us with the basics of Username/Email, password, and the user's first and last name. So really, only 4 columns in this table are 'required', but then we have these others that are just good standards to implement. For starters, there's User ID. This will just be a number that will go up by one every time a profile is created. This is good to have because it provides a unique identifier for each user. Granted, we'll also have the Username/Email as a unique identifier, but the ID is standard for "Primary Key", which will be referenced in a bit.
Next up is Status. Sometimes, a user will want to 'delete' their profile. But they also may want to come back. Because of this, it's sort of bad practice to do a "hard" delete from a database, which means to ACTUALLY remove it. So instead, we want a "soft" delete option. This is what we use the Status column for. If the user ever decides to cancel their account, we just change it to inactive. If they want to come back, change it back to active.
The next three are all similar, so we'll put them together. Date Created, Date Modified, and Last Login are all going to store date values. Date Created will only ever be used when the user is created. It's sort of a "member since" concept. Date Modified, we're going to update this any time another update is made. Be it a name change, password change, etc. Lastly, the Last Login column will be updated whenever the user logs in. Intent is pretty clear, here. We want to know how active users are.
One more thing worth mentioning, but we aren't going to flesh out in this post, is the password. We aren't going to store the actual password in the database. Instead, we'll store a "hashed" version of the password. It'll basically look like gibberish, but this will keep the user's password safe in the off-chance you do something wrong that results in a user's password being exposed.
Okay, so now we want to make at able for tasks. Technically, it's going to have NOTHING to do with users. Here's the columns we're going to have for tasks
So I'm sure you can figure out what all of these are for now, but I still want to mention a couple of things. First off, Task Name is soft of the task equivalent of a user's name. But this one isn't going to be restricted with the Unique flag. Common tasks may have the same name, like "clean room" or something standard. But that's fine, since we have the Task ID as our default identifier. The other thing I want to point out is status. We want different options than just whether or not it's active, so users can keep track of what's to be done.
Okay, so now we have our two tables. But we're not quite done just yet. We need a way to connect users to tasks. So we're going to make ONE more table. Assignments
Okay so now we have 3 IDs being used. Assignment ID will be our unique identifier, where User ID and Task ID will be what connects the two. This is where our database gets into "relational" territory. Each assignment will have User ID match the ID in the Users table, and the Task ID will match the ID in the Tasks table. We're also going to make sure they're noted as being a "Foreign key", so the database knows that they are connected. This isn't required, but it's good standard practice. Also, having this logic separated makes it incredibly easy to assign multiple tasks to a user, and even multiple users to a single task.
When you want to see all the users on a task, you ask the assignment tables for all of the rows where the Task ID is equal to the ID from the actual task. Now, you'll have a handful of User IDs that you can reach out again and get all of the data for each user. Super simple, easily scalable.
So now that we have our database built out, we need to build the API to handle all the traffic to said database. We don't want anyone having direct database access, so the API keeps it safe. Think of it as going to a restaurant (super common comparison, but here we go anyway). The front-end application would be the customer, the Database would be the kitchen. Well, you can't exactly go into the kitchen and tell the cooks what to do. So instead, you have a waiter (API) to go back to the kitchen, tell them what you need, then bring it out. We've discussed the basics of an API in more detail before, including why they're so useful. You're also going to want some way to authenticate requests made to the API. You'll want to make a decision on which language to use to build this. Personally, I think a good choice is PHP. I think it's an excellent first programming language to learn if you want to get into web development, and I go into the details in my blog about becoming fluent in PHP programming language.
A common way to handle this is called a JSON Web Token, and it's usually stored in the browser (or mobile application). This token is verified every time a request is made, If it is valid, and the user has permission to make the request, then you will get back some kind of data. This could be the information you're requesting, or just a "update successful" message when you make a change. Technically, we'd also want a fourth table for permissions, or we could add another column to the Users table for User Type. It could have options like "standard" or "administrator" that can only do certain things. But for now, we're not going to worry about that. Anyone can make tasks and assign any user to those tasks.
So once you've completed this part of your application, you will have finished the back-end. All of the data structure is set, and it's been secured behind a token validation process. The only thing that won't be "protected" by this validation process will be the ability to either create a profile or log in. Because obviously you can't validate something that doesn't exist yet, and you can't log in if you need to be logged in before you can log in. Makes sense, right? If it doesn't, don't worry too much. If you want to learn more about how to think like a programmer, we've got resources for that. Also, may want to take some time reading about how to prevent SQL injections.
This is a lot simpler in practice, and won't really require a lot of explanation. This is what the user will see. When they go to the application, they'll be either presented with a login screen or a list of tasks, depending on whether or not they've signed in yet. Essentially, it's a collection of web pages that display different data depending on what data they're requesting. And that's sort of all there really is to it. But I don't want to leave you entirely empty-handed on this side, so let's add in some recommendations.
Since this is a website designed to look and act like an application, rather than just a standard website for your local mom-and-pop shop, It's a good idea to use a front-end framework. The three big one's today are React, Angular, and Vue. Personally, I'd say you can eliminate Angular for most new projects. That's not to say that Angular is bad, just sort of more than you need these days. If you want a cross-platform app, for example, something that you KNOW you want to turn into a mobile application, and you want a single code base, go with React every time. Otherwise, I'd say go with Vue. For all intents and purposes, it's Angular without all of the extra baggage. Angular Lite, in a sense.
So now, you'll be spending all of your time making data requests and styling it to look nice and pretty. It sounds simple, and in theory, it is. From this point on, you'll be doing a lot of the same thing. You'll also be occasionally going back to the back-end of your project to make changes and improvements here and there. This is also where the concept of "feature creep" starts to sneak into your project. You'll have a lot of new ideas that you'll want to add to your task manager. But fortunately, we've started with that in mind. That's what scalability is: the ability to add new features to your project without having to re-work things.
You'll also want to plan out the user-flow. Think of what features are most important, and make them the easiest to get to. Also, something to take to mind with both UI and UX design, less is more. Try not to overload your application with bells and whistles. It needs to be simple to use, and everything needs to 'make sense' from a user's point of view. If you don't have a designer friend to help you out, or lack the design skills yourself (something I'm painfully guilty of) then look at other applications that you consider competitors of your app. Play with them, look for features that you may want to add to yours, and most importantly, look for flaws and improvements that can be made.
Congratulations. Your task manager is complete. Or is it?
Whatever you do, don't stop here. Especially if you're planning on trying to put it out for others to use and potentially monetize your application, you want to keep making improvements. Your first goal over-all for project-completion should be to get it to MVP, or Minimum-Viable-product status. Stick close to the core concepts of what your application is meant to do, and work on doing them insanely efficiently. Don't let feature creep kick in until AFTER you've made it past this point. The last thing you want to do is an application riddled with half-baked features, none of which that work.