Turns out you can't just put your data anywhere...

Gaining exposure to both frontend and backend coding frameworks has shed an embarrassing amount of light on how little I (and what I assume to be many other millions of internet users) actually understand the layers of protocol that make up the internet. I was mostly protected from this realization while learning JavaScript and React. I could perform CRUD operations through an API that would show up immediately on a readily accessible local db.json file lurking in my code editor. As I dove into server-side programming, however, I found myself often wondering where my data was actually going and what the benefits to server-side coding were. As it turns out, working with a web server and working with a local frontend database file are vastly different.

One significant difference between using server-side coding in tandem with a Web Application Framework like Sinatra and working with local database storage is the flexibility, robustness, and specificity of server-side HTTP requests. Working only in client-side code means that all fetch requests must be written and defined alongside user interface objects, navigation, and forms. Not only does compartmentalizing the Request-Response cycle separately from user-facing functionality deliver clean code, but it also means that backend programmers can define customized HTTP responses. Server-side code offers the ability to modify and return finely tailored data. In the example below, the application controller in our Ruby code makes use of previously defined, robust backend database methods to return a variety of responses. These methods, like .by_price, are often built upon huge libraries of useful code, like the .to_json and .first methods. Using client-side code to do the same work would require relying heavily on the few JavaScript and React methods at the developer’s fingertips (map, filter, find, and forEach).

Storing data and sending responses with server-side code is more practical than continuing to work with a frontend database, as well. While my server-side code does run locally, web servers at large are designed to handle multiple requests simultaneously from different users. A local database file will always only be accessible to a single user at a time. Writing code that only utilizes a local database is ultimately simpler, but much less realistic for creating widespread usable programs for users other than me. Local databases do not need to account for race conditions, which is when the outcome of an operation may be interrupted by users. For instance, if two users attempted to request and modify the same bit of data at the same time, or if a user canceled an initial HTTP request before the response was sent. Server-side coding ultimately needs to be powerful enough to account for race conditions with techniques like using locking or queueing mechanisms.

Storing data in the frontend versus the backend produces even more noticeable differences between the way data persists and is accessed. A local database file stores all the working data in a single file that can easily be read and written to. For instance, the programmer can modify a db.json file from within the frontend’s code editor. Those changes will show and persist when the app loads. This can be helpful for seeding data for an app or deleting any mistakes with the data. But with server-side code, the data is more formally structured and kept in a relational table. Because servers are designed for widespread usability, storing data across multiple requests, and in a way that can be accessed by all users of the application, is crucial. Furthermore, while local frontend databases can be useful in storing instances of one object, they do not excel in showing relationships between objects. Because Ruby has access to many powerful database libraries like SQL and ActiveRecord, it is easy to perform CRUD operations on a variety of objects with concise code.

Frontend local databases can be easily read and written to, but lack built in relationships between objects.

Backend or server-side databases use libraries to map out relationships between objects, making CRUD operations easier to perform on instances of many objects.

In conclusion, learning to code in Ruby has been an exciting journey, but it hasn't come without its share of challenges. One of the most significant hurdles I encountered was understanding the differences between a server and a local database file. I had to learn about databases and consider how to store data across multiple requests, which was different from the way I was used to working with data. However, with patience and persistence, I was able to overcome these challenges and build exciting web applications that leverage the full power of Ruby.

https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Introduction

https://www.cs.cornell.edu/courses/cs2110/2016fa/L25-Concurrency2/cs2110Concurrency2-6up.pdf