<?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: Ibrahim Mohammed</title>
    <description>The latest articles on DEV Community by Ibrahim Mohammed (@ibrahim_mohammed_47).</description>
    <link>https://dev.to/ibrahim_mohammed_47</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1672629%2F87b7c93e-c971-473e-93db-807ef0089953.jpg</url>
      <title>DEV Community: Ibrahim Mohammed</title>
      <link>https://dev.to/ibrahim_mohammed_47</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibrahim_mohammed_47"/>
    <language>en</language>
    <item>
      <title>From REST to MCP (2/2): The Design Shift</title>
      <dc:creator>Ibrahim Mohammed</dc:creator>
      <pubDate>Mon, 13 Jul 2026 16:41:54 +0000</pubDate>
      <link>https://dev.to/ibrahim_mohammed_47/from-rest-to-mcp-22-the-design-shift-4bda</link>
      <guid>https://dev.to/ibrahim_mohammed_47/from-rest-to-mcp-22-the-design-shift-4bda</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/ibrahim_mohammed_47/from-rest-to-mcp-12-different-dimensions-277j"&gt;part one&lt;/a&gt;, we saw why the environments of MCPs and REST APIs are fundamentally different, and therefore concluded that their design should also differ. In this article we will go through some MCP design good practices, but we will have a REST intro to each one. My goal is to elaborate the shift in design between the two.&lt;/p&gt;

&lt;p&gt;The examples below come from Sentry, Notion, GitHub and Stripe. We will see how the developers in those companies realized that fact that REST and MCP should have different design by comparing the way a specific operation is implemented in same company's REST API and MCP Server.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Design around intent
&lt;/h2&gt;

&lt;p&gt;REST APIs expose operations that are ideally built around &lt;strong&gt;resources&lt;/strong&gt;. They impose some level of granularity that might shift some of the orchestration/aggregation work to the client code. That work is developed and tested before the application is deployed.&lt;/p&gt;

&lt;p&gt;With MCP, the agent often builds that workflow at runtime. Which means the agent is now responsible for figuring out how to combine different tools to fulfill the user intent. That added responsibility simply means higher error probability and more context usage. To reduce that, we should design around &lt;strong&gt;user intents&lt;/strong&gt; not resources.&lt;/p&gt;

&lt;p&gt;A tool should represent one coherent user intent and push more of the deterministic orchestration into the server. This does not mean creating a &lt;code&gt;manage_everything&lt;/code&gt; tool. The useful boundary is an outcome that the agent can sensibly choose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Setting up a Sentry project requires separate REST operations across project, repository, and client-key resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;# Create the project
POST /api/0/teams/{organization_slug}/{team_slug}/projects/

# Link its repository
POST /api/0/projects/{organization_slug}/{project_slug}/repo/

# Retrieve an active client key and its DSN
GET /api/0/projects/{organization_slug}/{project_slug}/keys/

# Create a key only if no usable one exists
POST /api/0/projects/{organization_slug}/{project_slug}/keys/
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sentry documents these operations separately under &lt;a href="https://docs.sentry.io/api/projects/create-a-new-project/" rel="noopener noreferrer"&gt;Create a New Project&lt;/a&gt;, &lt;a href="https://docs.sentry.io/api/projects/link-a-repository-to-a-project/" rel="noopener noreferrer"&gt;Link a Repository to a Project&lt;/a&gt;, and the endpoints to &lt;a href="https://docs.sentry.io/api/projects/list-a-projects-client-keys/" rel="noopener noreferrer"&gt;list&lt;/a&gt; or &lt;a href="https://docs.sentry.io/api/projects/create-a-new-client-key/" rel="noopener noreferrer"&gt;create&lt;/a&gt; client keys. Its MCP server exposes the complete setup through one &lt;a href="https://github.com/getsentry/sentry-mcp/blob/main/packages/mcp-core/src/tools/catalog/create-project.ts" rel="noopener noreferrer"&gt;&lt;code&gt;create_project&lt;/code&gt;&lt;/a&gt; tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create_project(
  organizationSlug="acme",
  teamSlug="backend",
  name="payments-api",
  platform="python",
  repository="acme/payments"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool creates the project, connects the repository, retrieves an active DSN, and creates a fallback client key when needed. The agent chooses the setup outcome without carrying the project slug through the sequence or adding every intermediate response to the conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Batch repeated operations
&lt;/h2&gt;

&lt;p&gt;REST's uniform interface does not define a standard bulk-operation primitive, so APIs commonly scope changes to one item. That worked well enough when a person used a UI: create one page, fill it, then create the next. Human-paced interaction rarely needed many complete items at once.&lt;/p&gt;

&lt;p&gt;An agent creates a different workload. A user can ask for a research workspace, project plan, or book and expect several pages from one request. Without batching, the agent repeats the same tool call and rebuilds its arguments before checking each result. Every call consumes more context and gives the agent another chance to skip an item or let the inputs drift.&lt;/p&gt;

&lt;p&gt;A batch tool accepts the collection once and moves the loop into deterministic server code, or even a more efficient native bulk operation that our datastore supports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Notion's &lt;a href="https://developers.notion.com/reference/post-page" rel="noopener noreferrer"&gt;Create a page&lt;/a&gt; REST endpoint creates one page per request. Creating three pages under the same parent requires three calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /v1/pages  # "API migration"
POST /v1/pages  # "Launch checklist"
POST /v1/pages  # "Incident review"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notion's &lt;a href="https://developers.notion.com/guides/mcp/mcp-supported-tools#create-pages" rel="noopener noreferrer"&gt;&lt;code&gt;notion-create-pages&lt;/code&gt;&lt;/a&gt; MCP tool accepts the collection directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;notion-create-pages(
  parent={ page_id: "engineering_page_id" },
  pages=[
    { properties: { title: "API migration" }, content: "..." },
    { properties: { title: "Launch checklist" }, content: "..." },
    { properties: { title: "Incident review" }, content: "..." }
  ]
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding another page changes the collection, not the number of tool calls.&lt;/p&gt;

&lt;p&gt;Batching still needs a clear boundary. The tool should document its input limits, whether it processes items atomically or independently, and how it reports a partial failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Consolidate closely related operations
&lt;/h2&gt;

&lt;p&gt;REST can place related operations under different methods and routes. MCP puts every tool in one flat selection surface. Create and update are different actions, but separate tools can repeat the same context and compete for selection when they share most of their language and inputs.&lt;/p&gt;

&lt;p&gt;Consider an issue tracking conversation with an AI agent , a user may say "make sure this bug is tracked with the notes we discussed so far" without specifying whether to create an issue or update one. A single combined tool should handle both scenarios, whether the agent is delegating the decision into the tool implementation (&lt;code&gt;ex: upsertIssue(key, value)&lt;/code&gt;) or the agent is making the choice via an additional parameter (&lt;code&gt;ex: writeIssue(id?, value, operation = 'create' | 'update)&lt;/code&gt;). Any of those would be better than registering 2 tools.&lt;/p&gt;

&lt;p&gt;This saves context and can also improve selection accuracy. The &lt;a href="https://aclanthology.org/2026.acl-long.1573/" rel="noopener noreferrer"&gt;ToolScope study&lt;/a&gt; supports this narrower selection claim, not a rule to merge every related operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;GitHub's REST API exposes issue creation and update as 2 separate endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST  /repos/{owner}/{repo}/issues
PATCH /repos/{owner}/{repo}/issues/{issue_number}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub's &lt;a href="https://github.com/github/github-mcp-server/blob/c36e4e4493c76eafe2c1a9cbc5272e8eede29189/pkg/github/issues.go#L2130" rel="noopener noreferrer"&gt;&lt;code&gt;issue_write&lt;/code&gt;&lt;/a&gt; MCP tool groups them behind one explicit parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;issue_write(
  issue_number: number, # gets ignored if passed method is create
  method="create" | "update",
  owner: string,
  repo: string,
  title: string,
  # ... other 9 fields
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;method&lt;/code&gt; parameter keeps &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; distinct. If we were to keep create and update as 2 separate tools, that means we would be copying all the documentation for all 13 parameters across both tools, which would eventually bloat the context.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Make semantics explicit
&lt;/h2&gt;

&lt;p&gt;With REST, the URL identifies a resource and the HTTP method describes the operation. Status codes classify the result, while headers add protocol-level context. Application code interprets those signals through branches written by a developer.&lt;/p&gt;

&lt;p&gt;With MCP, an agent usually sees only a tool call and its result. It doesn't have a client-side logic that translates an HTTP status to a specific user facing message. A bare &lt;code&gt;Unauthorized&lt;/code&gt; leaves several questions open: what failed, whether state changed, and what the user should do next.&lt;/p&gt;

&lt;p&gt;The tool should turn that implicit contract into &lt;strong&gt;explicit&lt;/strong&gt; inputs and results. Detailed semantics give the model fewer interpretations and a safer recovery path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;A REST API may rely on the method, route, and status code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PATCH /orders/ORD-42
Content-Type: application/json

{
  "shipping_address": "12 Market Street, Cairo"
}

401 Unauthorized
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The programmed client's &lt;code&gt;401&lt;/code&gt; branch may already know how authentication works and which sign-in screen to open. The equivalent &lt;code&gt;update_order(order_id="ORD-42", shipping_address="12 Market Street, Cairo")&lt;/code&gt; tool should return that knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AUTHENTICATION_REQUIRED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The shipping address for ORD-42 was not updated because the store account session has expired."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"state_changed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recovery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ask the user to reconnect the store account through the account connection UI, then retry update_order with the same arguments. Do not ask for credentials in chat."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools" rel="noopener noreferrer"&gt;MCP specification&lt;/a&gt; supports structured results, so explicit feedback does not require giving up machine-readable errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Treat documentation as control flow
&lt;/h2&gt;

&lt;p&gt;With REST, developers usually read documentation while building an integration. Once the client ships, its integration logic keeps working even if the reference becomes incomplete, outdated, or buried in a Slack thread.&lt;/p&gt;

&lt;p&gt;With MCP, the agent reads the tool name, description, and parameter descriptions at runtime. Documentation does not just support the integration. It &lt;strong&gt;prompts the agent&lt;/strong&gt; and becomes an essential part of the control flow.&lt;/p&gt;

&lt;p&gt;The wording affects which tool the model selects and which arguments it builds. Changing a REST description does not change a client that has already compiled its integration logic. Changing an MCP description can change behavior while the schema and handler stay untouched. A commit named &lt;code&gt;docs: clarify wording&lt;/code&gt; can now change production behavior.&lt;/p&gt;

&lt;p&gt;Documentation changes can therefore cause regressions and should be tested against representative user requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Before invocation, the model may know a log-search capability only through this definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_logs(service, query, start_time, end_time)
"Search logs."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The description leaves important decisions to the model. It does not say which logs the tool searches, what identifies a service, how it interprets time ranges, or whether it includes audit events.&lt;/p&gt;

&lt;p&gt;A useful definition carries the knowledge that would otherwise live in an API guide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_logs(service, query, start_time, end_time)
"Search application logs when investigating runtime behavior. `service` must
match a deployed service name. Times are UTC and the range cannot exceed 24
hours. This tool does not search security audit events."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expanded description tells the model when to select the tool and how to construct a valid call.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Suggest relevant next actions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design#implement-hateoas" rel="noopener noreferrer"&gt;HATEOAS (Hypermedia as the Engine of Application State)&lt;/a&gt; is part of &lt;a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" rel="noopener noreferrer"&gt;REST's original uniform-interface constraint&lt;/a&gt;. It simply means the server should return links that describe valid next transitions. Most REST APIs ignore this part because they'd view as impractical (even though the REST author is &lt;a href="https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#:~:text=if%20the%20engine%20of%20application%20state%20(and%20hence%20the%20API)%20is%20not%20being%20driven%20by%20hypertext%2C%20then%20it%20cannot%20be%20RESTful%20and%20cannot%20be%20a%20REST%20API.%20Period" rel="noopener noreferrer"&gt;skeptical&lt;/a&gt; about APIs being called RESTful without HATEOS). Anyways, this concept should now be revived, it will be more relevant in an MCP than in a REST(or REST-ish) API.&lt;/p&gt;

&lt;p&gt;Again, an agent chooses the next step at runtime. If the result names a relevant tool, explains why it applies, and carries known arguments forward, the agent does not have to search the tool surface or infer the transition from raw state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Sentry's &lt;a href="https://github.com/getsentry/sentry-mcp/blob/main/packages/mcp-core/src/tools/catalog/get-trace-details.ts" rel="noopener noreferrer"&gt;&lt;code&gt;get_trace_details&lt;/code&gt;&lt;/a&gt; MCP tool does this in its response. When a trace contains an AI conversation, the result includes the trace summary and a structured &lt;code&gt;suggestedActions&lt;/code&gt; entry. &lt;a href="https://github.com/getsentry/sentry-mcp/blob/ce099fd251973774116749016847b78a6049ba0a/packages/mcp-core/src/tools/catalog/get-trace-details.test.ts#L717" rel="noopener noreferrer"&gt;The tool's response test&lt;/a&gt; covers this behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"structuredContent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"suggestedActions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tool_call"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"toolName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"execute_sentry_tool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"get_ai_conversation_details"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"organizationSlug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sentry-mcp-evals"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"conversationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"conv-trace-snapshot"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fetch the full transcript for this AI conversation."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response selects the next tool, explains why it applies, and carries forward the organization and conversation identifiers found in the trace. The agent can move from the trace overview to the full conversation without reconstructing that workflow from documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Support field filtering
&lt;/h2&gt;

&lt;p&gt;REST APIs commonly return a fixed resource representation, then let application code extract the fields it needs from it. &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design#implement-data-pagination-and-filtering" rel="noopener noreferrer"&gt;Client-defined projections&lt;/a&gt; is considered one of the best practices by Microsoft, although many REST APIs do not provide them. That's why we hear that one of GraphQL's advantages is that it promotes against &lt;a href="https://www.geeksforgeeks.org/graphql/what-are-over-fetching-and-under-fetching/" rel="noopener noreferrer"&gt;over-fetching&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With MCP, the tool should return the smallest complete result needed for the current decision. The model has to interpret every returned field, and common clients may keep the result in conversation history. Irrelevant data consumes context now and may keep consuming it on later turns.&lt;/p&gt;

&lt;p&gt;A smaller result also gives the model less state to distinguish before choosing its next action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;A REST field projection may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /customers/C-17?fields=id,name,riskStatus
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP tool can expose the same filtering idea directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inspect_customer(
  customer_id="C-17",
  fields=["customer_id", "display_name", "risk_status", "risk_reasons"]
)
→ {
    "customer_id": "C-17",
    "display_name": "Contoso Ltd.",
    "risk_status": "review",
    "risk_reasons": ["billing address changed after payment"]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both interfaces use the same projection pattern, and that is fine. With MCP, filtering matters more because every returned field may enter the model's context. The &lt;code&gt;fields&lt;/code&gt; parameter lets the agent request only the properties needed for its current decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Guard destructive operations
&lt;/h2&gt;

&lt;p&gt;With REST, an endpoint usually assumes that client code has already selected the intended operation and resource, this is enhanced by a good UI/UX that warns users of destructive operations, and the overall deterministic behavior of the app doesn't make this a big issue.&lt;/p&gt;

&lt;p&gt;With MCP, a model makes that choice at runtime. Schema and permission checks can show that a mutation is well-formed and allowed, but they cannot show that the agent understood what the user wanted.&lt;/p&gt;

&lt;p&gt;A tool can guard destructive operations before and after execution. Before the call, its description can instruct the agent to warn the user and ask for explicit confirmation. For higher-risk operations, the client can enforce that confirmation. After the call, the result should confirm what changed and provide a recovery path through soft deletion or a restorable backup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;remove_file(path)
"Remove a file. Before calling, warn the user that the file will be deleted and ask for explicit confirmation."

remove_file(path="/repo/config.yml")
→ {
    "removed": "/repo/config.yml",
    "state_changed": true,
    "backup_path": ".backups/7fd2/config.yml",
    "backup_expires_at": "2026-07-20T12:00:00Z"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This level of protection makes sense for deletion. Not every update needs the same ceremony.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Disclose tools progressively
&lt;/h2&gt;

&lt;p&gt;A REST API may expose hundreds of endpoints because each application selects the subset it needs during development. That selection happens once, before the application runs.&lt;/p&gt;

&lt;p&gt;An agent cannot make the same permanent selection because the useful subset depends on the current request. MCP clients should progressively disclose specialist tools as the user's intent becomes clearer.&lt;/p&gt;

&lt;p&gt;Tool definitions also consume context. Loading every definition at the start spends context on capabilities that may never be used and gives the model more similar options to confuse. Progressive disclosure adds a discovery step, but it narrows both the initial prompt and the selection problem when the full surface is large enough to justify it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Search-first meta-tools are common when an MCP server wraps a large API. &lt;a href="https://docs.stripe.com/mcp#tools" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; exposes a few broad tools instead of one tool per API method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stripe_api_search            → find the API method
stripe_api_details           → load its parameters
stripe_api_read / stripe_api_write → execute it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the selected method's details enter context. The extra discovery step makes sense for a large surface. Five clear tools do not need a meta-tool in front of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The backend capability may be the same, but the consumer is not. A REST client follows integration logic written during development. An agent chooses operations at runtime. Directly wrapping every REST endpoint preserves an interface designed for a different consumer, so the MCP interface must carry more of the knowledge that code previously supplied.&lt;/p&gt;

&lt;p&gt;This comparison is not exhaustive. Security, caching, and other operational dimensions introduce their own tradeoffs when the consumer is an agent. They deserve separate treatment and may become the subject of a future article.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>rest</category>
      <category>architecture</category>
    </item>
    <item>
      <title>From REST to MCP (1/2): Different Dimensions</title>
      <dc:creator>Ibrahim Mohammed</dc:creator>
      <pubDate>Sun, 12 Jul 2026 12:07:57 +0000</pubDate>
      <link>https://dev.to/ibrahim_mohammed_47/from-rest-to-mcp-12-different-dimensions-277j</link>
      <guid>https://dev.to/ibrahim_mohammed_47/from-rest-to-mcp-12-different-dimensions-277j</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;An MCP server can look like another API layer: expose existing REST endpoints as tools and call it a day.&lt;/p&gt;

&lt;p&gt;Both receive input, execute backend logic, and return a result. But they operate under different assumptions. This two-part series explains why directly wrapping REST APIs is a bad default. This first article covers the differences in their runtime environments. The second will discuss how those differences should affect MCP design (you already know how to design a &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design" rel="noopener noreferrer"&gt;good REST API&lt;/a&gt;). We can see those differences more clearly by comparing the two across several dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dimensions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The consumer
&lt;/h3&gt;

&lt;p&gt;With REST, developers encode control in application logic. The application knows when to call an endpoint, what arguments to send, and how to handle the response. Those decisions are made during development.&lt;/p&gt;

&lt;p&gt;With MCP tools, much of that control moves to the AI agent. The model interprets the request, chooses a tool, constructs its arguments, evaluates the result, and decides what to do next. The harness can restrict it, but the model is still part of the control flow. A REST client already knows why it is making a call. An agent must first decide whether a tool is relevant at all. &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools" rel="noopener noreferrer"&gt;MCP tools&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The context
&lt;/h3&gt;

&lt;p&gt;A REST application can draw from application state, cookies, memory, and user input. Code written by a developer determines which parts become request parameters.&lt;/p&gt;

&lt;p&gt;An agent can draw from the current request, conversation history, and previous tool results. The MCP server does not see this context automatically, but the model may turn parts of it into tool arguments at runtime. &lt;/p&gt;

&lt;p&gt;The difference is who selects what reaches the backend: predetermined code or a model reasoning over a changing conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The action model
&lt;/h3&gt;

&lt;p&gt;REST APIs tend to expose focused, fine-grained operations that application code can compose. Keeping endpoints simple and stable limits regressions because a developer has already written and tested the workflow that connects them.&lt;/p&gt;

&lt;p&gt;With MCP, the agent often constructs that workflow at runtime. Smaller operations give code more composability, but give an agent more choices, more intermediate results to interpret, and more opportunities to take a wrong turn. Copying a REST interface also copies assumptions about where the workflow lives and who composes it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The failure model
&lt;/h3&gt;

&lt;p&gt;A REST client can handle known status codes through explicit branches. Much of an error's meaning may exist only in the client code: the backend returns a code, and the application already knows the next step. Human-readable messages can become secondary output from the API. The backend and frontend developers agreed on this private language during their lunch break; the agent was not invited.&lt;/p&gt;

&lt;p&gt;An agent must interpret the failure at runtime. It may need to change an argument, ask the user, choose another tool, or stop. If a wrapped API returns only a status code or internal identifier, the agent loses the knowledge that used to live in the REST client. Machine-readable codes still matter, but the model also needs detailed and actionable feedback. &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools#error-handling" rel="noopener noreferrer"&gt;MCP tool error handling&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The state model
&lt;/h3&gt;

&lt;p&gt;REST is stateless, so each request contains the information needed to process it. The backend does not have to retain client session context, and requests remain independent from one another.&lt;/p&gt;

&lt;p&gt;MCP has a connection lifecycle that starts with initialization and may include a server-side session. FastMCP(famous MCP server implementation) uses stateful sessions by default, retaining a context for each client between requests. It also supports a stateless mode that creates a fresh context for every request. &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle" rel="noopener noreferrer"&gt;MCP lifecycle&lt;/a&gt;, &lt;a href="https://gofastmcp.com/deployment/http#understanding-sessions" rel="noopener noreferrer"&gt;FastMCP session modes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UPDATE: MCP is &lt;a href="https://modelcontextprotocol.io/seps/2575-stateless-mcp" rel="noopener noreferrer"&gt;becoming stateless&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The cost model
&lt;/h3&gt;

&lt;p&gt;In REST, a request and its response are normally processed once. They do not become persistent input that must be sent again with every later request. A REST response does its job and leaves; a retained tool result can move into the context window and keep charging rent. In common agent harnesses (like claude code), MCP tool inputs and outputs become part of conversation history. Every retained tool call takes space from the client's context window and is sent again on later model calls, so its cost compounds across the conversation. &lt;a href="https://modelcontextprotocol.io/docs/develop/clients/client-best-practices" rel="noopener noreferrer"&gt;MCP client best practices&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The trust boundary
&lt;/h3&gt;

&lt;p&gt;A malicious REST API can return hostile data, but a conventional client normally processes it through predetermined code, in addition to another layer of security usually imposed by the user facing client like browsers. &lt;/p&gt;

&lt;p&gt;An MCP tool interacts with a client whose control flow depends mostly on an LLM. Tool descriptions and results may influence what the model does next, opening the door to prompt injection, tool poisoning, context disclosure, or attempts to steer the agent toward another privileged tool.&lt;/p&gt;

&lt;p&gt;The outcome also depends on the underlying model and the harness around it. This gives third-party MCP servers a larger client-side attack surface than ordinary API integrations. The MCP specification tells clients to treat descriptions of tool behavior as untrusted and validate results before passing them to the model. Security research has also found familiar implementation vulnerabilities in tested MCP servers. &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools#security-considerations" rel="noopener noreferrer"&gt;MCP tool security considerations&lt;/a&gt;, &lt;a href="https://equixly.com/blog/2025/03/29/mcp-server-new-security-nightmare/" rel="noopener noreferrer"&gt;Equixly's MCP server research&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The backend capability may be the same, but the consumer is not. A REST API client follows a workflow that is predetermined and coded by a developer. An agent has more work to do, it plans on the fly, and puts a novel effort on each turn to determine what to do, including choosing a tool, calling it correctly, and combining it with other tools to satisfy user needs.&lt;/p&gt;

&lt;p&gt;Directly wrapping every REST endpoint preserves an interface designed for a different environment. If the consumer, context, action model, failure model, trust boundary, state model, and cost model are different, the interface design should probably be different too. That is the subject of part two.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>ai</category>
      <category>mcp</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Ultimate Guide to Coding Anarchy</title>
      <dc:creator>Ibrahim Mohammed</dc:creator>
      <pubDate>Mon, 24 Jun 2024 04:24:17 +0000</pubDate>
      <link>https://dev.to/ibrahim_mohammed_47/ultimate-guide-to-coding-anarchy-12po</link>
      <guid>https://dev.to/ibrahim_mohammed_47/ultimate-guide-to-coding-anarchy-12po</guid>
      <description>&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;Are you tired of writing boring, predictable code? Ready for a change? Well, buckle up! This guide provides you with 10 pieces of advice that will turn your codebase into a wild rollercoaster ride for anyone brave enough to maintain it! Warning: the advice in this article is sarcastic and should be reversed if you value your sanity (no shit, Sherlock).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Wet your code
&lt;/h3&gt;

&lt;p&gt;Do you remember that smart code snippet that handles user authentication you copied from StackOverflow? I want you to copy/paste that snippet all over the project. Don't wrap it in a function that has a meaningful name that can be called whenever needed. Don't make your code &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY&lt;/a&gt;. Why? The main benefit is whenever you find a bug in this snippet, you will go through a long and amusing journey of updating this snippet everywhere it's written. So Much Fun. It's also another way to force you and your team to revise your code from time to time. Your team will surely appreciate that.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Write smart one-liners
&lt;/h3&gt;

&lt;p&gt;Have you earned respect in your team yet? No? Here is what you need to do, fill the codebase with smart one-liners that only smart people like you can understand.&lt;br&gt;
Let me show you an example I like a lot, the following dumb simple easy-to-understand code wastes 3 lines from our precious javascript files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nc"&gt;If &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;If &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's upgrade/optimize this code, for example, look at how compact and smart this alternative is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you adapt yourself to this cryptic coding style, you will get 70x respected within your team, thank me later.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Be inconsistent and unconventional
&lt;/h3&gt;

&lt;p&gt;As an extension to the last advice, I want you to break out of conventions and liberate yourself from chains. Some people whine too much about how your code should be consistent and follow agreed-upon conventions. Those "clean coders" police are holding you back. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't limit yourself to a single casing style within a project, make sure your functions have at least 2 casing styles like &lt;code&gt;camelCase&lt;/code&gt; and &lt;code&gt;snake_case&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Also, your function names shouldn't follow the same naming style. That's too dull, some function names should be verbs, some should be nouns, and some should be adverbs! &lt;/li&gt;
&lt;li&gt;Always mix. Use a mix of callbacks, promises, async/await code. Use a mix of regular and arrow functions. Use mix classes and function constructors,...etc 
Within your programming language community, you would usually find one or two coding &lt;a href="https://google.github.io/styleguide/jsguide.html" rel="noopener noreferrer"&gt;styling guides&lt;/a&gt; to chain you, ignore those guides, and Just Be Creative!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Don't comment your code
&lt;/h3&gt;

&lt;p&gt;A wise man once said: "&lt;em&gt;Good code does not need comments&lt;/em&gt;". That's 100% true. Don't insult yourself by putting comments in your good code. Do you remember that 200-line critical function that handles user payments in the application? this one particularly shouldn't be commented, and all variables in it should have 2 or 3 character names. This function is too critical, so it should be optimized more than anything else! &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Nest your code
&lt;/h3&gt;

&lt;p&gt;Have you ever heard of "Code Aesthetics"? It's about making our code beautiful and amusing to look at. One way to achieve this is by making 3+ nesting levels of your code blocks. For example, don't write dull code like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkDiscountEligibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User data is missing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User age is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User must be at least 18 years old&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;membership&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Membership status is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;membership&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Only gold members are eligible for a discount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead try writing a beautiful skewed pyramid shaped code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkDiscountEligibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;membership&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;membership&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Only gold members can get discount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Membership status is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User must be at least 18 years old&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User age is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User data is missing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Hardcode stuff
&lt;/h3&gt;

&lt;p&gt;The more you Hardcode, the more Hardcore you are. Always hardcode configuration values, constants, and secrets(&lt;strong&gt;especially secrets&lt;/strong&gt;) instead of grouping them in a config file or something as simple as a&lt;code&gt;.env&lt;/code&gt; file. This will make your code comprehensive, have fewer dependencies, and also efficient(because no need to do additional lookups). You might ask what if we want to have different values for different environments? Simple do if conditions on the environment everywhere throughout the code. like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lifeSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;lifeSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev_blablabblalasec&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;lifeSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prod_blablahardcoresec&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hint: Don't follow &lt;a href="https://12factor.net/config" rel="noopener noreferrer"&gt;12 factor app rule&lt;/a&gt; about organizing configs, those people are not efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Don't handle errors
&lt;/h3&gt;

&lt;p&gt;Errors are so overrated. Don't think too much about errors and handling them. Always focus on happy scenarios, because again, handling errors implicitly means that your code is error-prone, so please don't insult yourself. Some programming languages like Rust and Go deal with errors as first-class citizens to promote error handling explicitly. I'll give you examples but please this is only to show you how self in-confident those language developers are:&lt;br&gt;
Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;read_file_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File contents: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading file: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Depend on global variables
&lt;/h3&gt;

&lt;p&gt;Maximize the dependence of global variables in your code. Why pass stuff as function arguments when you can make your entire codebase a creative playground? &lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;databaseConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;database.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;databaseConnection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`SELECT * FROM users WHERE id = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how we completely ignore &lt;a href="https://medium.com/@omar.saibaa/dependency-injection-simply-45252e2457a8" rel="noopener noreferrer"&gt;dependency injection&lt;/a&gt; and save an additional parameter by pulling &lt;code&gt;databaseConnection&lt;/code&gt; from thin air into the function? Some people would argue that this has multiple drawbacks, like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It makes the code less predictable &lt;/li&gt;
&lt;li&gt;It makes this function untestable&lt;/li&gt;
&lt;li&gt;1. Preventing the application of the &lt;a href="https://en.wikipedia.org/wiki/Unit_of_work" rel="noopener noreferrer"&gt;Unit of Work&lt;/a&gt; pattern to combine this function with others in a single transaction.
But who needs predictability when you can embrace spontaneous creativity? And testing? Who has time for testing in 2024? We are developers, not testers! I'm 100% sure those critics don't do testing themselves. And Unit of Work pattern? Sounds like extra work to me! Just... ignore them and enjoy the freedom of your creative coding!&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  9. Mutate objects by passing them to magic functions
&lt;/h3&gt;

&lt;p&gt;This is one of my favorites. I find a lot of creative people doing it without even reading my article. &lt;br&gt;
Look at this dull immutable version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;originalDate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./dates.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// cloning the date object&lt;/span&gt;
  &lt;span class="nx"&gt;newDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFullYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2024-06-24T00:00:00.000Z&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;updatedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;addYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2024-06-24T00:00:00.000Z (still as is)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updatedDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 2025-06-24T00:00:00.000Z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boring, right? Now, here's the "upgrade":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;originalDate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./dates.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFullYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2024-06-24T00:00:00.000Z&lt;/span&gt;
&lt;span class="nf"&gt;addYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2025-06-24T00:00:00.000Z (ta da!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isn't it thrilling? Now, anyone looking at &lt;code&gt;originalDate&lt;/code&gt; will have no idea how and where it's value got mutated. Perfect!&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Don't write secure code
&lt;/h3&gt;

&lt;p&gt;A lot of paranoid devs worry too much about security, but this paranoia weakens your relationship with your app users. Learn to love your users, and you won't love them until you trust them completely by writing code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/register&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; 
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, imagine a request like this (but don't worry, your users would never do that of course):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3000/register &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"username": "hacker", "role": "admin"}'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is what would be stored in our modern NoSQL store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ role: "admin", username: "hacker"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how effortless that is? Just merge everything from the request body into your sensitive data object. Who needs validation or sanitization? Trust your users—they always have your best interests at heart, right?&lt;br&gt;
Always think good of your dear users. After all, what's the worst that could happen?&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Congratulations! You've now learned the art of writing code that's sure to keep your fellow developers entertained and on their toes. By following these anti-patterns, you can inject a bit of excitement into your workday and create a codebase that's as unpredictable as it is "creative." Remember, consistency, maintainability, and security are just suggestions. True creativity lies in embracing the chaos and trusting that your users and colleagues will understand your genius. Happy coding!&lt;/p&gt;

</description>
      <category>coding</category>
      <category>programming</category>
      <category>cleancode</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
