Building my First Production App - and then Blogging on it

9 Minutes

charlie beemy profile picture
By
  • coding
  • building
  • indie development

Sections

It's been a long journey getting to this point - or I guess in relative terms it hasn't been that long.

A little bit of background on myself:

I graduated college as a business major. I took some computer science classes in high school and college, but a vast majority of what I know about web development was self-taught through online coursework and through trial and error. A lot of trial and error. 

In this blog post, I'm going to talk about my journey from knowing nothing about coding to building a production app (beemy - the one I'm blogging on right now!) + share some lessons I learned along the way. This is about 2 years in the making.

Figuring Out What to Learn

When you first make the decision to pursue programming, it's pretty exciting. You feel great resolve and an "I can do this mentality". You type in "How to code" in the Google search bar -> only to find yourself bombarded with all these different tutorials of different programming languages and frameworks all of which you have no idea what they are used for or what purpose they serve. As you attempt to piece together bits of information from the different tutorials (sometimes conflicting information), you begin questioning your life decisions and why human beings are meant to be on earth.

Figuring out what to learn or how to start will be the biggest obstacle you face when starting to code.

This is especially true if you come from 0 coding experience.

When I first decided that I wanted to at least learn a little bit of coding on the side, I was attending Zoom university during quarantine. It was my final year of college, and I found my business coursework was relatively lenient - specifically because everyone was still making the transition to online learning. I think I spent a solid 2-3 months just researching what kind of programming fields were available. Although some people might find it fun to explore the possibilities out their -> this was not a fun time for me. The process in my head went something like this:

OK, so these are the available developer/engineer paths available for me:

  • Data Science
  • UI/UX
  • Cloud Administration
  • Backend Engineer
  • Frontend Engineer
  • Full Stack Engineer
  • Designer
  • Blockchain Engineer
  • Kubernetes?!?!

Now, let's see how difficult each of these paths is and what I have to learn. And this process usually uncovered more information that made me question my life and why I even wanted to pursue programming in the first place.

Everyone will have their own journey, and I know my experience is not unique. I realized this: learning to code is not a binary decision. It is going to be one that you give up on several times over and revisit. But the more and more you revisit it, the more you will realize that you want to do it. If you don't revisit it, then you know it's not for you LOL.

!!!NOTE FOR UNIVERSITY STUDENTS!!!

If you are a University student (or have a friend, child, or relative who is a university student) - please take advantage of the Github Student Pack. It provides so many great resources to both learn how to code and tools to actually code. A lot of my foundational web development knowledge came from these free learning resources. My two favorites are 1-year free premium Canva (design tool) and 6 months free Frontend Masters (everything frontend related).

Why a Blog Builder?

Choosing to build a blog builder was actually a simple one. I wanted to gain experience building a full-stack application that had the potential into turning into something greater than a side project. On top of this, I wanted to build an app that I would actually use. And here I am using it right now.


The below sections are going to get a little more technical


Focusing on the Fundamentals

I'm a big believer in learning concepts over memorizing small tidbits of code. This basically means knowing how to go about solving a problem and what type of solution should be implemented rather than focusing on syntax. In other words - it's important to know what to Google. And if you've solved a problem before, you can solve it again! Over time, the concepts will turn into muscle memory, and writing the code will come naturally. 

Let's take the example of rendering blog pages. This is the thought process that I went through when building beemy as well. The main considerations I had were:

  • Articles had to load fast.

  • Articles had to come with great SEO and best practices for HTML structure.

  • Articles needed to be published, edited, and deleted almost instantaneously with a click of a button.

In order to accomplish these 3 requirements, there were 2 main options I considered:

  1. Server rendering each page request.

  2. Statically generating the blog page when an article is published.

Because I already understood the difference between client-side and server-side rendering, I could rule out rendering blogs on the client-side because that would prevent articles from having great SEO (understanding web fundamentals!). 

My go-to framework is Next.JS - what beemy is built with. Put simply, Next.JS supports both client-side and server-side rendering while enhancing the developer experience. This means that I can code faster with the framework. Although server rendering articles would have been fine, I believed that having them statistically generated would have been better because of faster page load times. The question was - how would I go about doing this? Luckily for me, Next.JS actually came out with on-demand revalidation around a month before I was thinking about this issue! It was like it was meant to be.

Technical Challenges

Backend

I struggled particularly with coding the backend for beemy. Prior, I had fairly little knowledge of APIs or databases. So I had to go through the whole process of weighing which service would be right for my use case (ex. SQL vs. NoSQL).

One particular challenge I faced was determining whether to use GraphQL or REST API. Here are the benefits and drawbacks that I encountered when using each:

GraphQL - Advantages

  • Can hit one endpoint -> /graphql/api. This takes away a lot of thought when it comes to structuring API endpoints.

  • Self documenting.

  • Built-in error handling and status codes.

  • Cached connections so I didn't have to reconnect to my database each time.

GraphQL - Disadvantages

  • Having to define each schema. This proved especially difficult for saving article data because I was using a third-party Editor -> Editor.JS

  • Having to redefine what variables you get back from a query when updating schemas. This can also be seen as an advantage, as it ensures each client-side query is compatible with what is returned from the server. However, in my case, it proved to be a headache at times.

  • Lots of overhead to get setup.

REST - Advantages

  • Very simple to set up.

  • Works.

REST - Disadvantages

  • Have to create a different endpoint for each resource.

  • Handling query variables in URL strings.

I feel like it would have been fine to pick one over the other, but I ultimately decided to use both GraphQL and REST to build my backend. I found the drawbacks of having to define my article data schema in GraphQL quite challenging, so I opted for REST for the article resource.

beemy uses BOTH GraphQL and REST for its backend

Frontend

Despite having a strong grasp of React, I feel like I always learn some small aspects of how it works almost every week.

The most difficult aspect of the Frontend is creating reusable components. An example of this was coding a reusable form system for submitting data. I was surprised that something so fundamental to the web had a lot of nuances baked in. This is where I had to interact with a React API I was unfamiliar with -> the React children API. Got a lot of insight into how React functions as a framework from it.

Architecting the Codebase

Knowing where to place files is hard because you don't know when you might reuse a piece of code. Or which function names might conflict. This was a major challenge I faced when building out this full-stack application. Next.JS provides pretty great guidelines for pages and components, but handling the database folder took a decent amount of thought. Ultimately, I felt it made sense to separate my client-side queries from my server-side database queries. I know - big revelation. I sectioned each folder corresponding to different resources, and then each file corresponds to the query type.

Coding it Yourself vs. Dependencies

Most of the time, solving a problem is not the hard part. It's typically finding the right solution for your specific use case. Chances are if you encounter a problem, someone else has encountered the same one as well. This is where it becomes very tempting to quickly install a solution out there in order to solve your problem. However, there are a couple of issues with this:

A temporary bandaid - You install the solution, and it works! For now. And then as your application grows, you realize you need to add an additional feature to that dependency you installed a week ago. Unfortunately, it doesn't support it. 

More features than you wanted - Many times, a dependency will do too much. In this scenario, it might be easier to just code it yourself.

Customizability - This is specific for frontend dependencies. Many times, a component isn't quite the way you wanted it to look, so you are going to have to apply some additional styling. This is usually not a problem, but if this is the case why not just build your own component in the first place? And adding any piece of content to that component will be very challenging as well, if not impossible.

It's a double-edged sword with dependencies. On one hand, it might be too much time for you to code yourself. In this case, you can live with some of the drawbacks. On the other hand, it might be beneficial to code it yourself if you know it's core to your application. I also want to make this very clear:

beemy's  entire Editor is a dependency

So I support dependencies! But wanted to point out some things to consider before you npm install or yarn add. Overall, the most important aspect of features is time spent vs. value gained -> thank you #BusinessMajor.

Dependencies and frameworks are great because it give everyone a system to follow.

Getting Stuck On Problems

Being stuck is the worst. Not knowing how to go forward or how to navigate a challenge. Even worse is when you realize a previous solution you implemented needs to be refactored because you didn't consider an edge case or how your application would grow. Chances are, you'll experience this quite often as a developer. The more you experience this, the more comfortable with the feeling.

When I'm stuck, I usually take a break from my code. Do something else. I'll take some time to recharge my brain, and many times the solution will actually come to me during my break. 

It's better to be to take a longer time to implement the right solution than to implement the wrong solution quickly.

I use a lot of time to just think

I worked on beemy alone and wrote all the code for it. This means that when I got stuck, I didn't have anyone I knew personally that I could ask for help. This felt pretty isolating sometimes. However, I think it's a really good time to be a solo developer because of all the free resources available online. An abundance of free dependencies, learning resources, and not to mention people to ask your questions to on the internet. If you are stuck on a problem - ask Reddit or Stack Overflow! Admittedly, I need to get better at this, but I think it's a really great skill to have: the ability to ask for help.

There were a couple of instances where I encountered a problem that I absolutely could not find the solution for online. If you are working with a new technology or interacting with a little-used API, this might happen to you as well. This is where being resourceful and having background knowledge comes in handy. Just keep on trying everything until something works! The first step to solving any problem is finding out why your code is breaking. Once you find this out, it becomes much easier to craft a solution.

Made with