{"id":10485,"date":"2023-12-06T08:22:34","date_gmt":"2023-12-06T08:22:34","guid":{"rendered":"https:\/\/smartreach.io\/blog\/?p=10485"},"modified":"2024-07-16T05:35:18","modified_gmt":"2024-07-16T05:35:18","slug":"how-to-structure-your-codebase","status":"publish","type":"post","link":"https:\/\/smartreach.io\/blog\/how-to-structure-your-codebase\/","title":{"rendered":"How to Structure Your Codebase?"},"content":{"rendered":"\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Congratulations! You just learned to code and got your dream job. But what next? Do you know how to write &#8220;good code&#8221;? What are the practices that you need to follow? Or how to structure your code base?<\/p>\n\n\n\n<p>If you have a driving license, you are familiar with the ups and downs of a government process.&nbsp;<\/p>\n\n\n\n<p>Just because a system works, it does not mean it&#8217;s good. It&#8217;s frustrating to go through the whole process of getting a license. I certainly wished for the process to be faster, less stressful, and easier to understand.<\/p>\n\n\n\n<p>Now imagine the same environment created in your workspace because of your code. Your code must be readable, DRY(Don&#8217;t Repeat Yourself), and modular.<\/p>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Importance of Codebase Structure<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-media-text is-stacked-on-mobile\" style=\"grid-template-columns:18% auto\"><figure class=\"wp-block-media-text__media\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"500\" src=\"https:\/\/smartreach.io\/blog\/wp-content\/uploads\/2023\/12\/pasted-image-0-1.png\" alt=\"\" class=\"wp-image-10473 size-full\" srcset=\"https:\/\/smartreach.io\/blog\/wp-content\/uploads\/2023\/12\/pasted-image-0-1.png 500w, https:\/\/smartreach.io\/blog\/wp-content\/uploads\/2023\/12\/pasted-image-0-1-300x300.png 300w, https:\/\/smartreach.io\/blog\/wp-content\/uploads\/2023\/12\/pasted-image-0-1-150x150.png 150w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/figure><div class=\"wp-block-media-text__content\">\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p style=\"font-size:clamp(16.834px, 1.052rem + ((1vw - 3.2px) * 0.716), 26px);\"><strong><em>&#8220;There is code that makes you exhale a long, relaxed and proud &#8220;ahh&#8221; when you look at it. Write that.&#8221;<\/em><\/strong><\/p>\n<cite><a href=\"https:\/\/linkedin.com\/in\/danielciocirlan\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Daniel Cioc\u00eerlan<\/a>, <a href=\"https:\/\/rockthejvm.com\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Rock the JVM<\/a>.<br><a href=\"https:\/\/www.linkedin.com\/posts\/danielciocirlan_beautifulengineering-developerlife-activity-6897060858514456576-pKqL?utm_source=share&amp;utm_medium=member_desktop\" target=\"_blank\" rel=\"noopener\" title=\"\">Source: LinkedIn<\/a><\/cite><\/blockquote>\n<\/div><\/div>\n\n\n\n<p>Poorly structured code can be difficult to read, debug, and maintain. It can also lead to bugs and security vulnerabilities.&nbsp;<\/p>\n\n\n\n<p>Well-structured code, on the other hand, is easy to understand, modify, and extend. It is also less likely to contain bugs and security vulnerabilities.<\/p>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">The Codebase Challenge<\/h2>\n\n\n\n<p>Let&#8217;s say you work for a <a href=\"https:\/\/smartreach.io\/blog\/best-sales-agency-in-dallas\/\" target=\"_blank\" rel=\"noopener\" title=\"\">sales company<\/a>, and your company is using SmartReach to do your sales outreach and manage your prospects.\u00a0<\/p>\n\n\n\n<p>Your company gives out bonuses based on how many prospects are interested.&nbsp;<\/p>\n\n\n\n<p>You are asked to make a new sales <a href=\"https:\/\/middleware.io\/blog\/api-monitoring-tools\/\" target=\"_blank\" rel=\"noopener\" title=\"\">monitoring app<\/a> for phones. On the App, a sales executive can track interested prospects in SmartReach and maximize their productivity.&nbsp;<\/p>\n\n\n\n<p>The App is making a GET call to <a href=\"https:\/\/smartreach.io\/api_docs\">SmartReach public API<\/a> and giving us updates on our prospects. Let&#8217;s try to write a good bit of code and let&#8217;s see how to structure it.&nbsp;<\/p>\n\n\n\n<p>Look at this code below and try to understand it. Do you think there are any errors in it?&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Api {\n   def get(p: Int) = Action.async(parse.json) { request =&gt;\n      ws.url(s\"https:\/\/api.smartreach.io\/api\/v1\/prospects?page=$p\")\n  .addHttpHeaders(\n    \"X-API-KEY\" -&gt; \"YOUR_API_KEY\"\n  )\n  .get()\n  .flatMap(r =&gt; {\n\n    if (r.status == 200) {\n        Res.Success(\"Success\", (response.json \\ \"data\").as&#91;JsValue])\n    } else {\n      Res.ServerError(\"Error\",new Exception((response.json \\ \"message\").as&#91;String]))\n    }\n\n  })\n   }\n}\n<\/code><\/pre>\n\n\n\n<p>This is a sample code that I have written to do the same.&nbsp;<\/p>\n\n\n\n<p>We&#8217;ll work on this code and make it more readable and appropriate. So that when you read it, you don&#8217;t get a headache.&nbsp;<\/p>\n\n\n\n<p>We will write the code in <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>. Scala is a JVM-based language. It is both an object-oriented and Functional Programming language.&nbsp;<\/p>\n\n\n\n<p>But the things we will see today will apply to coding in general. Let&#8217;s get into the refactors!<\/p>\n\n\n\n<div style=\"height:32px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Codebase Refactors<\/h2>\n\n\n\n<div style=\"height:42px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Naming Conventions and Code Comments<\/h3>\n\n\n\n<p>We live in an age of abbreviation, and it&#8217;s great for texting but not for coding.&nbsp;<\/p>\n\n\n\n<p>Descriptive names for variables, classes, functions, and objects are crucial. Think of your friend who will review the code or refactor it. You need them to stay your friend after they work on it, won&#8217;t you?&nbsp;<\/p>\n\n\n\n<p>Add comments while you are at it, and make your coworkers&#8217; jobs easy! Adding comments might not seem important, but when you or your coworker is debugging it later, you&#8217;ll appreciate it.&nbsp;<\/p>\n\n\n\n<p>Let&#8217;s see how our code looks after we implement these principles.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class ProspectsApi {\n\n\n   def getProspectsFromSmartReach(\n                                   page_number: Int\n                                  ) = Action.async(parse.json) { request =&gt;\n\n      \/\/public GET API from SmartReach to get the prospects by page number\n      \/\/Docs - https:\/\/smartreach.io\/api_docs#get-prospects\n      ws.url(s\"https:\/\/api.smartreach.io\/api\/v1\/prospects?page=$page_number\") \n  .addHttpHeaders(\n    \"X-API-KEY\" -&gt; \"YOUR_API_KEY\"\n  )\n  .get()\n  .flatMap(response =&gt; {\n    val status = response.status\n\n    if (status == 200) { \n       \/\/checking if the API call to SmartReach was success\n       \/*\n        {\n          \"status\": \"success\",\n          \"message\": \"Prospects found\",\n           \"data\": {\n                    \"prospects\": &#91;*List of prospects*]\n                   }\n          }\n        *\/\n        val prospects: List&#91;JsValue] = (response.json \\ \"data\" \\\\ \"prospects\").as&#91;List&#91;JsValue]]\n        Res.Success(\"Success\", prospects)\n    } else {\n      \/\/getting error message\n      \/\/Docs - https:\/\/smartreach.io\/api_docs#errors\n      val errorMessage: Exception = new Exception((response.json \\ \"message\").as&#91;String]) \n      Res.ServerError(\"Error\", errorMessage) \/\/ sending error to front end \n    }\n\n  })\n }\n}\n<\/code><\/pre>\n\n\n\n<p>If you were Paying attention, there were errors in the code! For example the parsing for the prospect was not correct.<\/p>\n\n\n\n<p>Adding some more context (with the help of comments and a good naming convention), we avoided those errors!<\/p>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Codebase Organization and Modularization<\/h3>\n\n\n\n<div style=\"height:32px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Everything is sitting together. Our code is looking good, and the application is pretty simple. Now that our code works and is much more readable, let&#8217;s move to the next issue.<\/p>\n\n\n\n<p>Imagine adding a filter system to this code. It will make it look drastically more complicated. What we would need is a more modular codebase.<\/p>\n\n\n\n<p>For modularization, we will break this code into smaller blocks, but how do we decide which block lives where?<\/p>\n\n\n\n<div style=\"height:26px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Directory Structure<\/h4>\n\n\n\n<p>A directory is a folder where your code stays, so make a new folder, and there is your directory!&nbsp;<\/p>\n\n\n\n<p>A directory can have your code files, or it can have more sub-directories. In our case, we will go for sub-directories. We will divide our code into four parts: models, DAO (Data Access Object), Services, and Controller.&nbsp;<\/p>\n\n\n\n<p>Of course, your company or app can go for a different directory structure.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/E13c7pL_t14DToy7CZIq2P8DMeHxUiLQ9uNkDiaXhajG8cyWcZ66nE6sSV74y0h5u2ISv_WIulWS_lX25V-wp3nmPDRSjIXmMP-v-jZPnMEwffef2NKasq3ZJ0BvJrkAS7zT0Cp1byZiEdUENz-ByB4\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Model<\/h4>\n\n\n\n<p>Models are the objects that we create to represent&nbsp; data. For example, let&#8217;s see how our Prospect model will look.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>case class Prospect(\n                     id: Long, \/\/id of the prospect in SmartReach \ndatabase\n                     first_name: String,\n                     last_name: String,\n                     email: String,\n                     company: String,\n                     city: String,\n                     country: String,\n                     prospect_category: String \/\/ Prospect category in \nSmartReach\n                     \/\/ can be \"interested\", \"not_interested\", \n\"not_now\", \"do_not_contact\" etc\n                   )\n<\/code><\/pre>\n\n\n\n<div style=\"height:21px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Data Access Object (DAO)<\/h4>\n\n\n\n<p>As the name suggests, we are looking at an object that will give us data access. It could be calling your database or third-party API.&nbsp;<\/p>\n\n\n\n<p>We will avoid adding logic in these files since we want this layer to be about pure IO operations.&nbsp;<\/p>\n\n\n\n<p>IO operations are the calls you make to an outside entity or an outside entity calling your system. This is where you can always expect failures. So we need to have a safeguard here.&nbsp;<\/p>\n\n\n\n<p>In Scala, we get <a href=\"https:\/\/www.baeldung.com\/scala\/monads\">Monads<\/a> that help us capture the failures. We are using <a href=\"https:\/\/docs.scala-lang.org\/overviews\/core\/futures.html\">Future<\/a> here.<\/p>\n\n\n\n<p>We will get the data from our source and put it into the respective model.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class SmartReachAPI {\n\n\n   def getProspects(\n                    page_number: Int\n                   )(implicit ws: WSClient,ec: ExecutionContext): Future&#91;List&#91;Prospect]] = {\n\n      \/\/public GET API from SmartReach to get the prospects by page number\n      \/\/Docs - https:\/\/smartreach.io\/api_docs#get-prospects\n      ws.url(s\"https:\/\/api.smartreach.io\/api\/v1\/prospects?page=$page_number\") \n  .addHttpHeaders(\n    \"X-API-KEY\" -&gt; \"YOUR_API_KEY\"\n  )\n  .get()\n  .flatMap(response =&gt; {\n    val status = response.status\n\n    if (status == 200) { \n       \/\/checking if the API call to SmartReach was success\n       \/*\n        {\n          \"status\": \"success\",\n          \"message\": \"Prospects found\",\n           \"data\": {\n                    \"prospects\": &#91;*List of prospects*]\n                   }\n          }\n        *\/\n        val prospects: List&#91;prospect] = (response.json \\ \"data\" \\\\ \"prospects\").as&#91;List&#91;Prospect]]\n        prospects\n    } else {\n      \/\/getting error message\n      \/\/Docs - https:\/\/smartreach.io\/api_docs#errors\n      val errorMessage: Exception = new Exception((response.json \\ \"message\").as&#91;String]) \n      throw errorMessage\n    }\n\n  })\n }\n}\n<\/code><\/pre>\n\n\n\n<div style=\"height:41px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Service<\/h4>\n\n\n\n<p>This is the magic layer.&nbsp;<\/p>\n\n\n\n<p>This is where our business logic stays, so this is where we will add our filter. And you will see how easy it will be for us to add more logic in this part of the code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class ProspectService {\n  val smartReachAPI = new SmartReachAPI\n\n   def filterOnlyInterestedProspects(\n                                     prospects: List&#91;Prospect]\n                                    ): List&#91;Prospect] = {\n      prospects.filter(p =&gt; p.prospect_category == \"interested\")\n   }\n   \n   def getInterestedProspects(\n                              page_number: Int\n                             )(implicit ws: WSClient,ec: ExecutionContext): Future&#91;List&#91;Prospect]] = {\n     val allProspects: Future&#91;List&#91;Prospects]] = smartReachAPI.getProspects(page_number = page_number)\n\n     allProspects.map{list_of_prospects =&gt; \n     filterOnlyInterestedProspects(prospects = list_of_prospects)\n\n     }\n   }\n}\n<\/code><\/pre>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Controller<\/h4>\n\n\n\n<p>This layer is the point of contact for your APIs.&nbsp;<\/p>\n\n\n\n<p>It might get called from your front end or a third-party user (via your API). We will get all the data we need from the call, and after the processing, this is where we will send the response.&nbsp;<\/p>\n\n\n\n<p>We will avoid logic here too, logic always goes in the service layer.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class ProspectController {\n  val prospectService = new ProspectService\n\n  def getInterestedProspects(\n                             page_number: Int\n                            ) = Action.async(parse.json) { request =&gt;\n     \n     prospectService\n       .getInterestedProspects(page_number = page_number)\n       .map{ intrested_prospects =&gt; \n          Res.Success(\"Success\", intrested_prospects)\n        }\n       .recover{ errorMessage =&gt; \n          Res.ServerError(\"Error\", errorMessage) \/\/ sending error to front end \n\n       }\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>class ProspectController {Our code is now cleaner and easier to manage, allowing for more efficient refactoring.&nbsp;<\/p>\n\n\n\n<p>We also have clear points of reference for adding logic, making database calls, or integrating new third-party APIs.<\/p>\n\n\n\n<div style=\"height:39px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Testing and Quality Assurance<\/h2>\n\n\n\n<p>Testing can seem laborious and repetitive, but it will be your friend if you know how to use it properly. Don&#8217;t worry; we will not write any more code files.&nbsp;<\/p>\n\n\n\n<p>Let&#8217;s see some principles we follow for a Spec file to be good.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Coverage: When writing Spec for a given function, the first step is to make sure that our Spec touches all the lines of code in the function.<\/li>\n\n\n\n<li>Fail first testing: The Spec file is to check how our code works under different cases. It is crucial to cover all possible failure cases to ensure proper error handling.<\/li>\n\n\n\n<li>Integration Tests: Unit Tests can only cover logic, but there can be issues with IO! One way to cover that is to <a href=\"https:\/\/testsigma.com\/guides\/integration-testing\/\" target=\"_blank\" rel=\"noopener\" title=\"\">run integration tests<\/a>.<\/li>\n<\/ol>\n\n\n\n<p>&nbsp;If you would like to read a blog on writing test cases with examples, let me know!<\/p>\n\n\n\n<div style=\"height:41px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Collaboration and Teamwork<\/h2>\n\n\n\n<p>We have seen a lot of tools in our arsenal. Let&#8217;s move to the big guns.&nbsp;<\/p>\n\n\n\n<p>The people around you will be the ones helping you grow exponentially. Remember this as a thumb rule while working: call someone if you get stuck at something for more than thirty minutes.<\/p>\n\n\n\n<p>It is the responsibility of the entire team, not just an individual, to create a solid codebase. Our profession might seem very introverted from the outside, but collaboration is the basis of coding. And this collaboration exists beyond companies.&nbsp;<\/p>\n\n\n\n<p>Places like GitHub, LeetCode, StackOverflow, and many more show how involved and social our community is. Remember, if you are facing an issue, you will find someone who has come across that issue before. Always be ready to ask for help.<\/p>\n\n\n\n<div style=\"height:51px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices for Code Documentation<\/h2>\n\n\n\n<p>I believe that good documentation is crucial both for your public API and internal code. Since we are talking about coding here, let&#8217;s focus on that here.<\/p>\n\n\n\n<p>But remember, adhering to best practices for code documentation will not only facilitate a smoother onboarding process but also provide you, and your team with clear and comprehensible insights into the codebase, accelerating your learning curve.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Pre-coding, Research&nbsp;<\/h3>\n\n\n\n<p>This is where we place all the data needed to start the project, from your system design to all the links to relevant docs.&nbsp;<\/p>\n\n\n\n<p>Pre-coding doc will include your new table structure and changes and links to third-party documentation. Preparation is half the battle won!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">During coding<\/h3>\n\n\n\n<p>This is where we add comments to the code and explanations in the code itself.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Post coding<\/h3>\n\n\n\n<p>This is where we add the directions on how to use the code, and how to make changes to it in the future.<\/p>\n\n\n\n<div style=\"height:41px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Good code follows good naming conventions, has modularization, is DRY, readable, and is covered by test-cases. To write good code, we need documentation, collaboration, and a lot of coffee.&nbsp;<\/p>\n\n\n\n<p>I tried giving examples of these and how we follow them in the <a href=\"https:\/\/smartreach.io\/\" target=\"_blank\" rel=\"noopener\" title=\"\">SmartReach<\/a> codebase, but how you achieve these principles in your organization might differ.&nbsp;<\/p>\n\n\n\n<p>If you have any insights on these codebase structure principles, do let me know.<\/p>\n\n\n\n<div style=\"height:84px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Congratulations! You just learned to code and got your dream job. But what next? Do you know how to write &#8220;good code&#8221;? What are the practices that you need to follow? Or how to structure your code base? If you have a driving license, you are familiar with the ups and downs of a government [&hellip;]<\/p>\n","protected":false},"author":26,"featured_media":10490,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[128],"tags":[197],"class_list":["post-10485","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-curiosity_corner","tag-curiosity-corner"],"blocksy_meta":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/smartreach.io\/blog\/wp-content\/uploads\/2023\/12\/tech-blog.png","_links":{"self":[{"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/posts\/10485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/users\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/comments?post=10485"}],"version-history":[{"count":9,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/posts\/10485\/revisions"}],"predecessor-version":[{"id":14597,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/posts\/10485\/revisions\/14597"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/media\/10490"}],"wp:attachment":[{"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/media?parent=10485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/categories?post=10485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartreach.io\/blog\/wp-json\/wp\/v2\/tags?post=10485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}