<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: FabriceMk</title>
    <description>The latest articles on DEV Community by FabriceMk (@fabricemk).</description>
    <link>https://dev.to/fabricemk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F318421%2F920413cf-320f-4455-8fab-0a85e2dd487c.png</url>
      <title>DEV Community: FabriceMk</title>
      <link>https://dev.to/fabricemk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fabricemk"/>
    <language>en</language>
    <item>
      <title>Guidelines to build good RESTful APIs - Part 4: Ops, Ops, Ops! and Final Word</title>
      <dc:creator>FabriceMk</dc:creator>
      <pubDate>Sun, 07 Mar 2021 07:16:19 +0000</pubDate>
      <link>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh</link>
      <guid>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh</guid>
      <description>&lt;p&gt;This current post is the last part of a 4 articles series about our &lt;strong&gt;Guidelines to build good RESTful APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can access the other articles from the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-1-introduction-and-design-phase-pif"&gt;Part 1: Introduction and Design Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300"&gt;Part 2: Implementation Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5"&gt;Part 3: Testing Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Part 4: Ops, Ops, Ops! and Final Word - You are reading this 😀&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠 "Ops, Ops, Ops"
&lt;/h2&gt;

&lt;p&gt;We finally reached the last part! I wanted to talk a bit about operations, especially the ones related to infrastructure and monitoring. Because now that you have the code and the tests, you need to host it somewhere and you want to make sure it continues to run well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6tz5V6cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w9vzvandyfepvwcmckr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6tz5V6cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w9vzvandyfepvwcmckr.png" alt="DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🌎 Have proper environments
&lt;/h2&gt;

&lt;p&gt;We use several environments for our development process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DEV&lt;/strong&gt; to push the latest changes by the developers and do initial testing and validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;STG&lt;/strong&gt; to execute more complete tests (QA Regressions, Performance, Security, Reliability etc...) with a version of the code we would like to push to PRD.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PRD&lt;/strong&gt; serving the application to the end-users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some teams may have more (like pre-release, alpha, beta etc...) but in our case those 3 are usually enough.&lt;/p&gt;

&lt;p&gt;We are working with flexible Cloud infrastructure so not everything may be applicable to you but here are some properties of our environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extensive of use automation and Infrastructure as Code&lt;/strong&gt;. We have Shell scripts, dedicated deployment servers like &lt;a href="https://octopus.com/"&gt;Octopus Deploy&lt;/a&gt; and we make use of &lt;a href="https://www.terraform.io/"&gt;Terraform&lt;/a&gt; when possible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating environments manually has a LOT of pitfalls. It's difficult to repeat, more error-prone and it's easier to introduce inconsistencies. You can play around for prototyping with a sandbox environment but once you want to create a proper DEV, try to immediately automate as much as you can.&lt;/li&gt;
&lt;li&gt;Allows for easy thrashing and recreation of temporary environments that can be useful for some specific tasks or disaster recovery.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;STG is as close as possible to PRD&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have seen some STG environments that were totally different from their PRD counterparts. This defeats the purpose of STG altogether. It is supposed to "replicate" PRD so you can test with confidence before releasing. You end up having changes and operations that are PRD specific that cannot be tested and can lead to mistakes and ultimately downtime.&lt;/li&gt;
&lt;li&gt;It doesn't mean that STG has to be an exact copy to PRD all the times though. For costs reasons, we usually have STG as a shrunk down version of PRD most of the time. It has the same components but with less instances for example. But combined with the extensive automation we can easily scale STG to PRD levels for important operations like Performance Testing. And we can then shrink it down when not actively in use.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DEV is a cost-efficient environment&lt;/strong&gt; that should be easy to recreate as it's the most unstable by nature. We don't hesitate to have databases running as containers instead of dedicated VMs for example. The size is small and we try to keep it to a single region when most of our STG and PRD are deployed on multiple regions or availability zones.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the popularity of Docker, Docker Compose or Kubernetes, we try more and more to create entire environments on demand for Local and DEV so parallel features in development can be tested in their dedicated isolated instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗 Build Once, Deploy Anywhere
&lt;/h2&gt;

&lt;p&gt;When you promote your application from one environment to the next one in your pipeline, make sure that you &lt;strong&gt;ONLY PERFORM CONFIGURATION CHANGES&lt;/strong&gt;. The rule is to have the same code artifact across environments and just inject different configurations.&lt;/p&gt;

&lt;p&gt;I have seen some build pipelines that perform a full rebuild of the entire application for each environment. It's not great as every time you build, differences that are outside of your control can sneak in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A transitive dependency may have been upgraded if your package manager doesn't support full dependencies snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your build toolchain has changed between 2 deployments (like a plugin or server upgrade).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By building only once, you remove the &lt;strong&gt;&lt;em&gt;Code&lt;/em&gt;&lt;/strong&gt; as a potential source of issue between environments and can focus on the &lt;strong&gt;&lt;em&gt;Configuration&lt;/em&gt;&lt;/strong&gt; or the &lt;strong&gt;&lt;em&gt;Infrastructure&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔃 Have a Deployment Strategy
&lt;/h2&gt;

&lt;p&gt;I remember the &lt;em&gt;old days&lt;/em&gt; of being an IT student and pushing my new website version by uploading and overwriting files directly with my FTP Client.&lt;/p&gt;

&lt;p&gt;This should stay memories, don't do that on your production APIs please 😱&lt;/p&gt;

&lt;p&gt;Having a proper &lt;strong&gt;Deployment Strategy&lt;/strong&gt; is necessary to aim for "Stress Free" releases. It can help to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid downtime during the deployment of a new version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be able to rollback fast if a new version is causing issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test a new version on real PRD infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find more details on well-known strategies on the following link: &lt;a href="https://thenewstack.io/deployment-strategies/"&gt;Six Strategies for Application Deployment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--46tK8upX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rbgye9f138o1e4xcwgc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--46tK8upX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rbgye9f138o1e4xcwgc.png" alt="Deployment Strategies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your infrastructure may facilitate the implementation of some strategies. For example Azure App Services has easy &lt;strong&gt;&lt;em&gt;Blue/Green&lt;/em&gt;&lt;/strong&gt; deployments while &lt;strong&gt;&lt;em&gt;Rolling Release&lt;/em&gt;&lt;/strong&gt; is available out-of-the-box on Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🕵️‍♂️ Observability and Alerting
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;What's worse than having errors in Production? - Having to debug without any details about them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last thing you want when you are trying to fix your API in Production is to spend hours to even identify what is wrong. When developers work locally, they use various tools to find issues: debuggers, profilers or something as simple as a &lt;code&gt;printf/console.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The goal is the same, having more insights.&lt;/p&gt;

&lt;p&gt;This also applies to systems as a whole. If you have an issue on your API (it's becoming slow or unresponsive, it starts returning a lot of HTTP 5xx errors etc...) &lt;strong&gt;you need data to help you to find the cause&lt;/strong&gt;. The 3 main types of data fulfilling that purpose are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logs&lt;/strong&gt; like exceptions happening on the application level or errors outputs on the system level etc...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt; like the CPU percentage of VMs, the number of failed requests, the response time etc...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Traces&lt;/strong&gt; like a waterfall view of a request going through different components.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I invite you to read the following article &lt;a href="https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/ch04.html"&gt;The Three Pillars of Observability&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developers need to ensure their application can generate logs in case of errors for debugging purposes. Various languages and frameworks have dedicated tools like &lt;strong&gt;Logs Managers&lt;/strong&gt;. These logs then can be collected on some system that allows for consultation and ideally have search capabilities like &lt;a href="https://www.elastic.co/what-is/elk-stack"&gt;ELK&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cloud/Infrastructure providers and DevOps are more in charge of gathering metrics of the infrastructure and the different components. You need to be able to see if the traffic to your API is growing, if the disks of your VMs are getting full or if the CPUs are maxed out when receiving a spike of traffic.&lt;/p&gt;

&lt;p&gt;All those data can also be used to set up triggerable alerts when some threshold or changes in behavior start to happen. Systems with proper alerting systems try to detect Production issues as quick as possible in order to minimize downtime. But they can also help to detect small hidden issues that can grow: if you start seeing the response time increasing release after release, you might want to scale or optimize some parts of your system before it becomes a bigger problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Word
&lt;/h2&gt;

&lt;p&gt;That's it! You now have an overview of the general practices our team use and I hope it will help you to build better APIs.&lt;/p&gt;

&lt;p&gt;But don't &lt;strong&gt;blindly&lt;/strong&gt; follow any guidelines list you find on the net!&lt;/p&gt;

&lt;p&gt;Each project has its own specifics and context. The goal was to provide a baseline you can then adapt or extend to your likings. Evaluate each item of this list and then you can decide which one to apply.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Guidelines to build good RESTful APIs - Part 3: Testing Phase</title>
      <dc:creator>FabriceMk</dc:creator>
      <pubDate>Sun, 07 Mar 2021 07:14:05 +0000</pubDate>
      <link>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5</link>
      <guid>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5</guid>
      <description>&lt;p&gt;This current post is the 3rd part of a 4 articles series about our &lt;strong&gt;Guidelines to build good RESTful APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can access the other articles from the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-1-introduction-and-design-phase-pif"&gt;Part 1: Introduction and Design Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300"&gt;Part 2: Implementation Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Part 3: Testing Phase - You are reading this 😀&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh"&gt;Part 4: Ops, Ops, Ops! and Final Word&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧐 "Does it even work?"
&lt;/h2&gt;

&lt;p&gt;Testing is an important step in our development lifecycle and we have different types of tests in every project. They all have their specificities so we try to have a balanced mix of all of them.&lt;/p&gt;

&lt;p&gt;You may have seen this pyramid about testing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrit0dfc2jlkh84tharb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrit0dfc2jlkh84tharb.png" alt="Testing Pyramid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of the time we follow this pattern with a lot of automated unit tests. As we move into integration and E2E tests the amount of tests decreases as it becomes more and more expensive to write and run them.&lt;/p&gt;

&lt;p&gt;The priority of the tests depends on your project. For example when we inherit from an existing API with no tests at all, we prefer to focus on E2E and integration first as they are better to detect regressions on the "product behavior".&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Unit Testing
&lt;/h2&gt;

&lt;p&gt;Reference: &lt;a href="https://en.wikipedia.org/wiki/Unit_testing" rel="noopener noreferrer"&gt;Wikipedia article about Unit Testing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our team, unit tests are mandatory when building new web APIs. They are &lt;strong&gt;written and maintained by the developers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are the closest to the code and are tightly coupled with the language or framework you are using. As such they need to be also treated as code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Aim for good quality. Avoid silly logic, name your variables properly, run linters on unit tests code!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn how to properly use the testing frameworks at your disposition. Testing frameworks are usually powerful but can be very complex at the same time. You should spend the appropriate amount of time to to feel comfortable with them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make good use of support helpers like mocking/stubbing or assertions libraries, efficient runners... They can dramatically help to have more readable or simpler tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They should be reviewed!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One note though: we noticed that trying to get rid of all copy-paste and have reusable functions for absolutely everything like the application code could lead to hard-to-read tests. That's why we often have specific coding rules (and linter rules) for unit tests that are a bit more relaxed. It's up to you and your team to find the balance that works well.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Find some problems early in the development phase (especially bugs and implementation flaws)&lt;/td&gt;
&lt;td&gt;Cannot detect broader errors (created by the interactions of several components together)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast to execute&lt;/td&gt;
&lt;td&gt;Can give a false sense of security if you rely only on them and on metrics like coverage (100% coverage =/= bug-free)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Helps a lot to be more confident during refactorings&lt;/td&gt;
&lt;td&gt;Need to find a good balance between reusability and readability in the tests codebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can act as some type of documentation&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are automated by nature&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🧩 Integration and End-to-End Testing
&lt;/h2&gt;

&lt;p&gt;Those tests are mostly &lt;strong&gt;under the responsibility of our dedicated QA team&lt;/strong&gt;. They test bigger chunks of the codebase/product at the same time and have higher value when we test the overall product.&lt;/p&gt;

&lt;p&gt;The QA team usually comes up with test scenarios once the products specs are done. The developers then review those scenarios and give feedback to QA engineers from a different point of view. It also helps the developers to better understand the test suites and anticipate issues when they change some parts of the implementation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cover test scenarios closer to real use-cases and product specs&lt;/td&gt;
&lt;td&gt;Take more time to implement and automate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can be compared directly to specs&lt;/td&gt;
&lt;td&gt;Slower to execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-value to detect product regressions&lt;/td&gt;
&lt;td&gt;Don't cover everything and focus only on the main flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can also act as some type of documentation&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🏎 Performance Testing
&lt;/h2&gt;

&lt;p&gt;The APIs our team builds are mainly consumed by mobile applications and may have to serve &lt;strong&gt;up to several tens of millions requests per day&lt;/strong&gt;. Some of those APIs also have to deliver important content for the applications to work properly: &lt;strong&gt;API performance needs to be tested&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before the initial release of an API, we benchmark our different endpoints (with the help of specialized tools like &lt;a href="https://locust.io/" rel="noopener noreferrer"&gt;Locust&lt;/a&gt;, &lt;a href="https://gatling.io/" rel="noopener noreferrer"&gt;Gatling&lt;/a&gt; or &lt;a href="https://k6.io/" rel="noopener noreferrer"&gt;k6&lt;/a&gt;) in order to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Measure the max capacity of our systems&lt;/strong&gt;. How many requests/clients we can support and keep an "acceptable" response time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Detect which components are the bottlenecks&lt;/strong&gt;. Is the database slowing down everything? Are the connections pools properly configured? Is the Load Balancer big enough? etc... They may require immediate fixing/mitigation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Study the scalability of the different components&lt;/strong&gt;. How much more traffic we can sustain if we double the memory of that component? How are the infrastructure costs increasing with the traffic scale?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those numbers are precious to evaluate the cost of the system at several scales, guarantee the response time for a specific number of clients etc...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance testing is not straightforward&lt;/strong&gt; and requires a &lt;strong&gt;strict&lt;/strong&gt; test protocol. It can also be time consuming. Not all APIs need it but ask yourself those questions:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"If our product becomes popular, will our systems scale? How easy and fast will it be? How big is the growth/financial/reputation impact if the system cannot sustain the traffic?".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you work on such sensitive APIs, prepare and run Performance Testing before the initial release. Ideally, you want to monitor that performance continuously and make sure the performance doesn't degrade over time.&lt;/p&gt;

&lt;p&gt;It's a big topic on its own but here are some resources that could help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.guru99.com/performance-testing.html" rel="noopener noreferrer"&gt;https://www.guru99.com/performance-testing.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://techbeacon.com/app-dev-testing/how-create-highly-effective-performance-tests" rel="noopener noreferrer"&gt;https://techbeacon.com/app-dev-testing/how-create-highly-effective-performance-tests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💪 Reliability Testing
&lt;/h2&gt;

&lt;p&gt;Reliability Testing aims to confirm &lt;strong&gt;how your system reacts when one or several components face different levels of degradation&lt;/strong&gt;. As for Performance Testing, not every API needs it. But if your API is an important piece for the continuity of service of your business, you need to think about reliability testing.&lt;/p&gt;

&lt;p&gt;During the design phase, the architect or the developers may introduce some redundancy like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Having several instances of the web API so if one becomes unhealthy, the service is not totally down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having multiple database nodes like a Primary-Secondary failover setup, a triple-node cluster etc...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy the service on multiple datacenters/regions/cloud providers to cope with geo-localized issues (regional disaster, power outage, network issue etc...)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's very good! But in reality, things are rarely so simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Maybe you didn't configure the services properly to take advantage of that redundancy (some databases require that the code handle some aspects of the failover).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maybe your supposedly "optional" cache layer breaks your entire application if it becomes unavailable temporarily.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What seems nice on paper needs to be tested in real conditions&lt;/strong&gt;. You have to make sure all the mechanisms you put in place are working as expected in case of emergency. Similar to this famous quote about backups:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There’s No Point in Backing Up Your Data if You Don’t Test Your Backup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You want to know if your API continues to work after the failure of some components.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many requests will be dropped during the failover? Is it acceptable?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The testing is very specific to each project but try to figure out scenarios you want to confirm depending on the quality of service you need to guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 Security testing
&lt;/h2&gt;

&lt;p&gt;At Rakuten we are lucky to have teams dedicated to Cyber Security. They help us to test the software we build. For web APIs, it often involves &lt;strong&gt;Penetration Testing&lt;/strong&gt; by using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Source code scanning&lt;/strong&gt; to detect vulnerable software versions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port scanning&lt;/strong&gt; to detect vulnerabilities on the network stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SQL, XSS injections&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They can also help &lt;strong&gt;at the design phase&lt;/strong&gt; to make sure you don't introduce fundamental business flaws that would require a major revamp later.&lt;/p&gt;

&lt;p&gt;So problem solved? Not exactly.&lt;/p&gt;

&lt;p&gt;Having dedicated security engineers is nice but &lt;strong&gt;software security should involve EVERYONE developing the product&lt;/strong&gt;: the product specs, the developers, the QA and also the DevOps in charge of setting up the infrastructure.&lt;/p&gt;

&lt;p&gt;The involvement of the different roles is important to apply the concept called &lt;strong&gt;Defense In Depth&lt;/strong&gt; where multiple layers of security are in place to minimize the chances of attacks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxv1augen7q7p63toadot.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxv1augen7q7p63toadot.jpg" alt="Defense in Depth"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For every new API our team builds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We go through a Security Audit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And we make sure that all issues are fixed before release.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ideal situation would be also to have some automated security diagnostics running against your APIs as part of the CI/CD pipeline and detect more issues by yourself as early as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⏩ Next part
&lt;/h2&gt;

&lt;p&gt;After testing you now need to deploy your API and make sure it runs properly at all time. Let's talk about operations in the final article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh"&gt;Part 4: Ops, Ops, Ops! and Final Word&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>api</category>
      <category>rest</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Guidelines to build good RESTful APIs - Part 2: Implementation Phase</title>
      <dc:creator>FabriceMk</dc:creator>
      <pubDate>Tue, 23 Feb 2021 12:12:59 +0000</pubDate>
      <link>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300</link>
      <guid>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300</guid>
      <description>&lt;p&gt;This current post is a 2nd part of a 4 articles series about our &lt;strong&gt;Guidelines to build good RESTful APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can access the other articles from the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-1-introduction-and-design-phase-pif"&gt;Part 1: Introduction and Design Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Part 2: Implementation Phase - You are reading this 😀&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5"&gt;Part 3: Testing Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh"&gt;Part 4: Ops, Ops, Ops! and Final Word&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ "Just Do It!"
&lt;/h2&gt;

&lt;p&gt;Now that you have designed our API, it's coding time! I have selected a couple of good practices that can be applied independently of the language or web framework you may be using.&lt;/p&gt;

&lt;h2&gt;
  
  
  🍰 Layer your API
&lt;/h2&gt;

&lt;p&gt;Except for Proofs of Concept or prototypes, &lt;strong&gt;layer your implementation from the start!&lt;/strong&gt; You won't gain anything by not doing it.&lt;/p&gt;

&lt;p&gt;Layering is a way to organize your code for separation of concerns and follows those rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Each layer depends on the layers beneath it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A layer should have no knowledge about any layer above it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a layering we often use in our APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Edge layer&lt;/strong&gt; (alternative names: Controller/Presentation layer) hosting the API Controllers, the various helpers and middlewares. It's the layer in contact with the requests from the clients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Logic layer&lt;/strong&gt; (alternative names: Business/Application/Domain layer) usually implementing the business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Data layer&lt;/strong&gt; (alternative name: Persistence layer) that handle the data persistence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we look closer, we realize that the nature of the code of each layer is different:&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Edge layer&lt;/strong&gt; for example is usually tightly coupled to the web framework you are using. The way controllers, middlewares, validators are implemented can be vastly different between 2 frameworks even if they are written in the same language. It also handles a lot things related to HTTP requests and responses.&lt;/p&gt;

&lt;p&gt;On the other hand, the &lt;strong&gt;Logic Layer&lt;/strong&gt; is often made of plain objects representing your business entities and code taking care of manipulating them.&lt;/p&gt;

&lt;p&gt;As for the &lt;strong&gt;Data Layer&lt;/strong&gt;, you are likely to import and use clients that "talk" with specific databases, external APIs or some type of storage. And each usually come with their own specific and complex objects (the way MongoDB and MySQL represent and expose queries and results objects to you are totally different for example).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dro8ZWsj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igj748u5buoc7uec89gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dro8ZWsj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igj748u5buoc7uec89gd.png" alt="API Layering"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The benefits of layering are then more obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clearer scope for each layer in terms of role but also in terms of dependencies. It's unlikely that your Logic Layer will have to deal with HTTP Requests objects or HTTP codes for example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier to expand or modify one specific part of your code without impacting the rest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved reusability. For example, you can have multiple endpoints on the Edge Layer that use the same logic in the Logic Layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clearer testability. A layer like the Data Layer is usually more difficult to unit test than the Logic Layer. But because they are clearly separated, you have a more comprehensive view of the testing status of each layer and may decide to rely on unit tests for the Logic Layer and more on integration tests for the Data Layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the reason given by developers that use the "kitchen sink" approach is that their API is not complex enough to require layering and it's a waste of time. I don't buy that, &lt;strong&gt;it takes literally a few of seconds/minutes to separate your layers&lt;/strong&gt;. And naming is the longest part of it. Of course just creating a bunch of folders is not enoughs. You have to think where each piece of code goes and make sure it stays organized thorough the development but it can still be a lightweight process. But it's nothing compared to the hours of refactoring a "simple" API with all the codebase in the controllers can cause once it has evolved into a "spaghetti mess".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Layering your codebase brings tons of benefits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Layer from the beginning, it costs nothing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  👻 The power of abstraction
&lt;/h2&gt;

&lt;p&gt;Even if a layer creates some degree of isolation, it still needs to communicate with components located in lower layers. This communication can become messy if not controlled properly.&lt;/p&gt;

&lt;p&gt;A solution we use in our team is proper abstraction and clear contracts between layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goal is to avoid leaking implementation details.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'll take a simplified example of a Data Layer having to interact with a MySQL database with the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Data Layer is using a third-party MySQL client &lt;code&gt;MySqlClient&lt;/code&gt; to connect and perform queries to a remote MySQL database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;MySqlClient&lt;/code&gt; uses its own objects to represent results &lt;code&gt;MySqlResult&lt;/code&gt; or errors &lt;code&gt;MySqlError&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a typical API, the Logic Layer needs to fetch data from the database in order to execute some business logic. And it instructs the Data Layer to do so.&lt;/p&gt;

&lt;p&gt;A mistake would be for the Logic Layer to directly communicate with &lt;code&gt;MySqlClient&lt;/code&gt;. Because it would then become tightly coupled to the underlying database: MySQL. The code in the Logic Layer would have to extract results from &lt;code&gt;MySqlResult&lt;/code&gt;and handle &lt;code&gt;MySqlErrors&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What happens if one day MySQL doesn't suit the needs anymore and we want to to change it to let's say MongoDB? We would have to change the Data Layer and all those MySQL related objects that leaked in the Logic Layer.&lt;/p&gt;

&lt;p&gt;A solution would be to abstract your &lt;code&gt;MySqlClient&lt;/code&gt; by something like &lt;code&gt;DatabaseClient&lt;/code&gt; and have your custom and more generic &lt;code&gt;DatabaseResult&lt;/code&gt; and &lt;code&gt;DatabaseError&lt;/code&gt;. The Logic Layer would then interact with this abstract client instead of &lt;code&gt;MySqlClient&lt;/code&gt;. That way, your Logic Layer becomes unaware of the real database you are using. And it's good as it doesn't care! It just wants the results and knows that errors can happen with the "database".&lt;/p&gt;

&lt;p&gt;The other advantage is that the communication "contract" between the layers is less sensitive to changes. You better understand how the data flows between your layers.&lt;/p&gt;

&lt;p&gt;I concede that you don't change your database everyday but this concept can be generalized to a multitude of other situations.&lt;/p&gt;

&lt;p&gt;In the recent years, we had to migrate several of our databases hosted on Azure Cosmos DB to MongoDB and we were able to do it by just adding a new implementation class and making a small change of configuration in all the impacted APIs. &lt;strong&gt;Abstracting the Data Layer only took us a couple of minutes in the early stages of the project and saved us hours of refactoring of the Logic Layer code and its unit tests&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Having clear communication contracts helps to understand the data flow between layers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't leak implementation details especially between layers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstraction makes the code more flexible to changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstraction reinforce the isolation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstract from the beginning, it's not expensive.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎣 Beware of your exception catching
&lt;/h2&gt;

&lt;p&gt;I won't get into the details because exception handling is a rich topic but you have to know that unmanaged and non-consistent exception handling can become a huge source of issues in your API.&lt;/p&gt;

&lt;p&gt;Keep the following rules in mind instead, they work quite well for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If you encounter an exception, catch it only if you can handle it locally. If not, it's better to let it resurface to the upper levels.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Badly handled exceptions in the bottom layers can silence real problems.&lt;/li&gt;
&lt;li&gt;Don't catch and re-throw a more generic exception, you may lose important information.&lt;/li&gt;
&lt;li&gt;It's fine to wrap an exception with one of your own exception (but make sure you don't remove information in the process).&lt;/li&gt;
&lt;li&gt;In most cases don't catch and re-throw the same exception if you just want to log (see next point).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a general exception catcher on the Edge Layer that will catch any non-handled exception that managed to bubble to the surface. This is where you will be able to handle the logging in a centralized way and standardize error messages that are returned with HTTP 500 for example.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⏩ Next part
&lt;/h2&gt;

&lt;p&gt;You have written all the code needed for your API to run. We now need to check it works properly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5"&gt;Part 3: Testing Phase&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>api</category>
      <category>webdev</category>
      <category>rest</category>
    </item>
    <item>
      <title>Guidelines to build good RESTful APIs - Part 1: Introduction and Design Phase</title>
      <dc:creator>FabriceMk</dc:creator>
      <pubDate>Tue, 23 Feb 2021 12:11:24 +0000</pubDate>
      <link>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-1-introduction-and-design-phase-pif</link>
      <guid>https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-1-introduction-and-design-phase-pif</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I have been working on RESTful APIs for several years at Rakuten in Tokyo using various languages and web frameworks. Their size ranged from tiny single-endpoint micro-services to big and complex ones. And most of them had pretty decent quality.&lt;/p&gt;

&lt;p&gt;But I also met some APIs that were much more difficult to work with. Not because the problem they tried to solve was complex, but because they all had accumulation of issues during their development. Issues that could and should have been avoided because they weren't proper thoughtful trade-offs.&lt;/p&gt;

&lt;p&gt;Software development in a company has its own challenges, namely resources allocation, schedules and deadlines, business requirements etc... The key to build good quality APIs even with those constraints is to properly choose your battles.&lt;/p&gt;

&lt;p&gt;For that reason I would like to share a list of practices our team tries to apply every time we build a RESTful Web API. We will go through the following development lifecycle and point the particular areas that require focus.&lt;/p&gt;

&lt;p&gt;Note: for readability reasons, the article will be split into several parts and the links to each of them will be updated once they are published.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Part 1: Introduction and Design Phase - You are reading this 😀&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300"&gt;Part 2: Implementation Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-3-testing-phase-11b5"&gt;Part 3: Testing Phase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-4-ops-ops-ops-and-final-word-bnh"&gt;Part 4: Ops, Ops, Ops! and Final Word&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4epJiCEf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3buxjzxx5egtndt3yhzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4epJiCEf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3buxjzxx5egtndt3yhzu.png" alt="checklist-icon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🗺 "Does anyone have a plan?"
&lt;/h2&gt;

&lt;p&gt;First, a reminder about typical properties of most APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An API solely exists to deliver a SERVICE by being consumed by "clients"&lt;/strong&gt;. It is similar to services providers in real life, be it a shop, a restaurant, the postal services etc... You want to deliver a good service and the clients to be "happy". If you ever had to use and consume a third-party APIs in your projects, maybe you have experienced the following:

&lt;ul&gt;
&lt;li&gt;I wonder if there is an endpoint to request multiple results in a single request instead of sending a lot of single result requests?&lt;/li&gt;
&lt;li&gt;Is it possible to filter the results? I don't need all these.&lt;/li&gt;
&lt;li&gt;Do I really need to provide all those hundred parameters that looks like they could be optional?&lt;/li&gt;
&lt;li&gt;I followed the example but I keep getting an error with no explanation.&lt;/li&gt;
&lt;li&gt;Where is the documentation?&lt;/li&gt;
&lt;li&gt;Why the naming is so inconsistent? It's confusing.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you are the one building the API, you also want to ask yourself those same questions. You are not building an API for the sake of building it, someone will use it! It can be yourself, your teammates, another team in the company or even clients who are paying for your product.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modifying an API Contract is HARD&lt;/strong&gt;, especially if your API is public. Any change on your API behavior can &lt;em&gt;break&lt;/em&gt; the clients and their applications (it can cause crashes and affect millions of users). In practice, an API will always have to evolve to a certain degree. There are techniques to manage these changes like &lt;em&gt;API versioning&lt;/em&gt; or &lt;em&gt;backwards-compatibility&lt;/em&gt; support, but it will always be a tricky exercise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why you &lt;strong&gt;WANT&lt;/strong&gt; to spend time on designing your API. It's the phase where you can create early mistakes that may have a huge impact on your API usability. Those mistakes are also often the most difficult to fix at a later stage. The time spent can vary depending on the size of the API, if it's public facing with a lot of clients etc... You don't need 10 hours of design for a throw-away API only used for some prototype but keep that in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠ Make sure you understand REST
&lt;/h2&gt;

&lt;p&gt;If your answer to the question &lt;em&gt;"What is REST for you?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;is just &lt;em&gt;"it's about using GET, POST and DELETE"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It's probably a good idea to refresh your memory a bit by reading the following article: &lt;a href="https://restfulapi.net/"&gt;https://restfulapi.net/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's well written and concise. You also have more details if you want to dig a bit deeper.&lt;/p&gt;

&lt;p&gt;I insist on having solid fundamentals because REST has a lot of misconceptions about what it does and doesn't enforce.&lt;/p&gt;

&lt;p&gt;For example and contrary to the popular belief, REST doesn't tell you which HTTP method (GET, POST, PUT, DELETE) you should use for operations as REST is not even technically tied to HTTP.&lt;/p&gt;

&lt;p&gt;It is therefore more productive to know exactly the constraints of the REST architecture, work with them and know which parts of the design require you to take more complex decisions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It's bold but you NEED to know and understand REST to build good RESTful APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having solid foundations will let you focus on the more custom (and more interesting) parts of your design.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💦 Naming and endpoint structure is hard but there are good practices out there
&lt;/h2&gt;

&lt;p&gt;When designing your API contract, the first difficulty is to &lt;strong&gt;come up with a proper hierarchy for your endpoints and NAME them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AKDgq-7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gqaw3qoy3t0p0ss3lka.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AKDgq-7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gqaw3qoy3t0p0ss3lka.jpg" alt="naming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;REST asks you to organize your data around &lt;em&gt;Resources&lt;/em&gt; but doesn't enforce any specific way to create a proper hierarchy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A large number of people wrongly relate resource methods to HTTP GET/PUT/POST/DELETE methods. Roy Fielding has never mentioned any recommendation around which method to be used in which condition. All he emphasizes is that it should be uniform interface. If you decide HTTP POST will be used for updating a resource – rather than most people recommend HTTP PUT – it’s alright and application interface will be RESTful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice, most of the public APIs follow some conventions considered as "reasonable". By following the same conventions, you help other developers to understand your API faster as they are used to see those patterns. Here is a very good (and short) list of some popular naming conventions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://restfulapi.net/resource-naming/"&gt;REST Resource Naming Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among some of those naming guidelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use nouns&lt;/strong&gt; to represent resources: &lt;code&gt;api/my-resource/&lt;/code&gt;, &lt;code&gt;api/my-other-resource&lt;/code&gt;, &lt;code&gt;api/my-resource/{id}/sub-resource&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid verbs&lt;/strong&gt; especially if they are mirroring what the HTTP methods could perform (in an HTTP context): Avoid &lt;code&gt;api/delete_my-resource&lt;/code&gt; and &lt;code&gt;api/get_my-resource&lt;/code&gt; when you can simple have &lt;code&gt;HTTP DELETE api/my-resource&lt;/code&gt; and &lt;code&gt;HTTP GET api/my-resource&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BE CONSISTENT!&lt;/strong&gt; You don't want the same parameters to have totally different names in 2 similar endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would lie if I say that every time we design APIs in our team everything goes well. We sometimes have "passionate" discussions and 2 developers may propose different designs that are technically correct and elegant. As mentioned earlier, there are a lot of things REST doesn't enforce. At times like this, it's not worth wasting too much time on it. Pick one, and stick with this design philosophy for your entire API. The key is consistency.&lt;/p&gt;

&lt;p&gt;One of my personal tip is to read the documentation and the API contracts of popular open APIs accessible on the Internet. It gives good examples and can be source of inspiration. Here are some of my favorites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/free-pro-team@latest/rest/reference/projects"&gt;Github API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/api/management/v2/#!/Users/get_users"&gt;Auth0 API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.marvel.com/docs"&gt;Marvel API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Using common naming conventions makes your API more predictable and easier to understand by other developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You don't have to start from scratch and reinvent the wheel, a lot of people came up with those battle-tested naming and structure recommendations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST is flexible enough to give you freedom but always plan wisely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔎 Always have your design proposition be reviewed by your peers
&lt;/h2&gt;

&lt;p&gt;The "passionate" discussions I have mentioned earlier are not considered a bad thing in our team. Quite the opposite, we encourage challenges when designing new systems. Having various people and their own knowledge, vision and skills can help to find mistakes, typos but also fundamental design issues. These issues can be costly at a later stage of the development so you want to detect them as early as possible.&lt;/p&gt;

&lt;p&gt;We started recently to &lt;strong&gt;involve not only developers&lt;/strong&gt; in that review process &lt;strong&gt;but also our QA engineers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The QA Team will be the first real client using your API&lt;/strong&gt;. As such, it is in a formidable position to detect validation mistakes, ask more details about unclear specifications and make sure the product scenarios are covered.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;"What's the exact format of that parameter representing a date? A timestamp? An ISO 8601?"&lt;/li&gt;
&lt;li&gt;"What supposed to happen if no result is found?"&lt;/li&gt;
&lt;li&gt;"Are we okay with an error or do we prefer an empty response?"&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Everyone's opinion is valuable as long as it's communicated in a constructive way&lt;/strong&gt;. When you give a comment, have an objection or wish to give a proposition, always explain properly your reasoning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;More people and more point of views: Less blind spots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's an excellent knowledge-transfer practice of the specs of the product when performed with a constructive mindset.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📃 Document your API
&lt;/h2&gt;

&lt;p&gt;I know a lot of developers don't like writing it and find it boring. But if there is something you should not skip when building a Web API, it's the &lt;strong&gt;DOCUMENTATION&lt;/strong&gt;. Again, the main purpose of an API is to be used. You don't want your clients to spend hours or days trying to figure out your endpoints location, the format of the parameters or the required headers.&lt;/p&gt;

&lt;p&gt;The minimum should be the list of all endpoints with their:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP methods&lt;/li&gt;
&lt;li&gt;List of headers/path/query parameters with their validation&lt;/li&gt;
&lt;li&gt;The format of the body&lt;/li&gt;
&lt;li&gt;Response and error codes and response payloads schemas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can write your documentation with the &lt;strong&gt;OpenAPI specifications&lt;/strong&gt; (formerly known as the &lt;a href="https://swagger.io/docs/specification/about/"&gt;Swagger Specification&lt;/a&gt;). It quite popular and there is an entire ecosystem of tools built on top of them. But as long as your documentation is accessible and you give enough information for your API to be used, it's the most important.&lt;/p&gt;

&lt;p&gt;It's also easier to write the documentation as you design and review your API contract. It will serve as a proper reference for the implementation and the testing.&lt;/p&gt;

&lt;p&gt;I suggest you to look at the documentation of the following APIs. You will notice that they go further than a simple endpoints list. They also describe the global concepts and the entities they are using and also have interactive parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stripe.com/docs/api"&gt;Stripe API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.twilio.com/docs/usage/api"&gt;Twilio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key-points&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An API without documentation is almost useless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The documentation serves as a reference for the different team members and roles. This can help avoid misunderstandings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having a documentation early will be useful on ALL the following steps of the development cycle.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⏩ Next part
&lt;/h2&gt;

&lt;p&gt;Now that we have designed our API, it's time to write some code and make it real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/fabricemk/guidelines-to-build-good-restful-apis-part-2-implementation-phase-2300"&gt;Part 2: Implementation Phase&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>api</category>
      <category>webdev</category>
      <category>rest</category>
    </item>
  </channel>
</rss>
