<?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: Sahil Khurana</title>
    <description>The latest articles on DEV Community by Sahil Khurana (@sahil_khurana_486f374ecf2).</description>
    <link>https://dev.to/sahil_khurana_486f374ecf2</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%2F3911388%2F81bf0e28-1844-48e4-8e2d-1c321202e68d.jpg</url>
      <title>DEV Community: Sahil Khurana</title>
      <link>https://dev.to/sahil_khurana_486f374ecf2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahil_khurana_486f374ecf2"/>
    <language>en</language>
    <item>
      <title>5 Benefits of Using Node JS for API Development</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Thu, 09 Jul 2026 06:05:12 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/5-benefits-of-using-node-js-for-api-development-17c2</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/5-benefits-of-using-node-js-for-api-development-17c2</guid>
      <description>&lt;p&gt;Netflix, Uber, PayPal, LinkedIn, GitHub.&lt;/p&gt;

&lt;p&gt;Five companies that collectively handle billions of API calls every day. All of them run Node.js on the backend. At some point, you stop treating that as a coincidence and start asking why.&lt;/p&gt;

&lt;p&gt;Node.js was built by Ryan Dahl in 2009. The problem he was solving: traditional server I/O was blocking, slow, and memory-hungry by design. His fix was a runtime built on Chrome's V8 engine that processes requests asynchronously on a single event loop thread. The architecture he built to solve that specific problem turns out to be almost exactly what modern API development needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The non-blocking I/O model is what makes Node.js actually fast under load — not benchmark-fast, production-fast. Thousands of concurrent connections without the thread-per-request memory overhead.&lt;/p&gt;

&lt;p&gt;JavaScript on both ends of the stack is a real productivity gain. Shared validation logic, shared type definitions, developers who can move across the stack without retraining.&lt;/p&gt;

&lt;p&gt;npm has over two million packages. The useful API development subset — Express, Fastify, NestJS, Prisma, Socket.io — is mature, well-maintained, and saves months of build time.&lt;/p&gt;

&lt;p&gt;Netflix cut startup time by 70% switching to Node.js. PayPal doubled requests per second with 35% faster response times. Those numbers come from engineering teams with no interest in marketing claims.&lt;/p&gt;

&lt;p&gt;Real-time features — chat, live dashboards, collaborative tools — are a natural fit. The same event loop that handles REST requests handles WebSocket connections without separate infrastructure.&lt;/p&gt;

&lt;p&gt;Why Does Your App Need API Development?&lt;/p&gt;

&lt;p&gt;The short version: APIs are how different parts of a system talk to each other, and how your system talks to anything outside itself.&lt;/p&gt;

&lt;p&gt;Less abstract version — a mobile app fetches user data through an API. Authenticates sessions through an API. Sends push notifications through an API. A healthcare app routes patient data between appointment systems, records, and billing. IoT devices send readings up and receive configuration down. The whole thing is APIs.&lt;/p&gt;

&lt;p&gt;What this means practically: the API layer isn't a feature sitting alongside the application. It's the connective layer that makes the application functional. Build it poorly and everything that depends on it — which is everything — pays the price.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Developers Prefer Using Node.js for API Development?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;High Performance &amp;amp; Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two things drive performance in Node.js. Worth understanding both, because "it's fast" is not an explanation.&lt;/p&gt;

&lt;p&gt;First: V8. Google's JavaScript engine compiles JavaScript directly to machine code rather than interpreting it at runtime. That's why execution is fast — the CPU isn't reading translated instructions, it's running the code directly.&lt;/p&gt;

&lt;p&gt;Second: the event loop. Most server architectures spawn a new thread for each incoming request. Threads are expensive — they consume memory, and switching between them under load burns CPU. Node.js uses one thread and an event loop. A request comes in, I/O operations get dispatched asynchronously, the loop keeps running and handles the next request. Nothing blocks.&lt;/p&gt;

&lt;p&gt;In practice, a Node.js server handling 10,000 concurrent connections uses a fraction of the memory a thread-per-request model would. That gap grows as concurrency grows. For high-traffic APIs — which most APIs become eventually — the difference is significant. Horizontal scaling is also clean: the cluster module spreads work across CPU cores, and deploying behind a load balancer adds capacity without touching the architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Asynchronous &amp;amp; Non-Blocking I/O&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is the one that matters most for API work specifically.&lt;/p&gt;

&lt;p&gt;In a blocking architecture, when the API calls the database, the thread waits. Can't handle another request until the query returns. 50ms per query, 200 concurrent users — the math deteriorates fast.&lt;/p&gt;

&lt;p&gt;Node.js doesn't wait. Database query gets dispatched, a callback or promise registers, the event loop keeps processing. When the query returns, the callback fires. Nothing sat idle.&lt;/p&gt;

&lt;p&gt;PayPal measured this in production: double the requests per second, 35% faster response times. That's not a controlled benchmark — that's a migration from Java to Node.js on a live system. The improvement held.&lt;/p&gt;

&lt;p&gt;The honest limitation: CPU-intensive work breaks this model. Long computations occupy the event loop and block everything behind them. For heavy data processing, machine learning inference, or anything compute-bound — Node.js is the wrong choice and you should pick something else. For I/O-heavy APIs, which describes the majority of API work, it's well-suited.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Single Programming Language (JavaScript)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;JavaScript front-to-back sounds like a developer convenience. The actual benefit runs deeper than that.&lt;/p&gt;

&lt;p&gt;Validation logic written once runs in both places. Data models defined once get shared. With TypeScript — which Node.js supports fully — type definitions synchronized between the API contract and the consuming client code means a whole class of mismatch bugs stops existing.&lt;/p&gt;

&lt;p&gt;Team flexibility is real too. A developer who works across both layers doesn't shift mental contexts between Python and JavaScript. On smaller teams especially, the ability to move people between frontend and backend without a retraining cycle is meaningful capacity. The cognitive overhead of maintaining two separate language contexts on a long engagement adds up — removing it doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Rich Ecosystem &amp;amp; NPM Packages&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Two million packages on npm. The number is absurd and mostly noise. The relevant subset for API development is manageable and genuinely excellent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frameworks&lt;/strong&gt;: Express.js is the baseline — minimal, flexible, and so widely used that answers to every possible question already exist. Fastify is faster and stricter by design, better for teams that want performance and don't mind its conventions. NestJS is TypeScript-first with a structured, opinionated architecture — increasingly the choice for larger teams where enforced conventions matter more than flexibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database access&lt;/strong&gt;: Mongoose for MongoDB, Sequelize for relational databases, Prisma for type-safe queries with less boilerplate than either. Pick based on your database and how much you care about type safety at the query level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth and security&lt;/strong&gt;: jsonwebtoken handles JWT signing and verification. bcrypt handles password hashing. helmet sets security-relevant HTTP headers automatically. These three cover the fundamentals for most API authentication setups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time&lt;/strong&gt;: Socket.io runs on top of the same Express server handling REST endpoints. No separate infrastructure, no separate service — WebSocket support sits alongside the existing API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;: Jest for unit and integration tests, Supertest for HTTP endpoint testing directly. Both integrate cleanly with the Node.js ecosystem.&lt;/p&gt;

&lt;p&gt;The package quality at the top of the npm ecosystem is high. These libraries are maintained by teams with years of production experience behind them. Using them means the months someone spent getting JWT refresh token rotation right, or getting bcrypt cost factors tuned, or handling CORS edge cases properly — you get that work for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Microservices &amp;amp; Real-Time Capabilities&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The same design that makes Node.js handle concurrent REST requests well makes it a natural fit for two things that show up constantly in modern API architecture.&lt;/p&gt;

&lt;p&gt;Microservices need fast startup, low memory per instance, and independent deployability. Node.js startup is measured in milliseconds. Memory per service instance is low. Each service is a standalone process — deploying it doesn't touch anything else. For containerized environments where services scale up and down based on traffic, those properties matter.&lt;/p&gt;

&lt;p&gt;Real-time means persistent connections where the server pushes updates to clients as events occur. Chat applications, live dashboards, collaborative editing, order tracking, anything that updates without the user refreshing. Node.js handles this natively — the event loop was designed for exactly this kind of workload. Socket.io makes implementing it on top of an existing API server straightforward. You're not running a separate real-time service. You're extending what you already have.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Which Kind of App Do You Need API Development for?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every modern application needs a well-designed API layer. The technology question is which requirements should drive the choice.&lt;/p&gt;

&lt;p&gt;Node.js makes sense when: concurrent connections are high, the workload is I/O-heavy rather than compute-heavy, real-time features are on the roadmap, or the team is already working in JavaScript and the shared-language benefits are real.&lt;/p&gt;

&lt;p&gt;Node.js makes less sense when the work is genuinely CPU-intensive, the team has deep existing expertise in Go or Python, and the switching cost outweighs the gains, or the application is primarily batch-processing oriented.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014 and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/node-js-for-api-development/" rel="noopener noreferrer"&gt;5 Benefits of Using Node JS for API Development&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>java</category>
      <category>node</category>
    </item>
    <item>
      <title>How Can PHP Development Help You Launch Faster and Scale Smarter?</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Wed, 08 Jul 2026 06:35:14 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/how-can-php-development-help-you-launch-faster-and-scale-smarter-2mp3</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/how-can-php-development-help-you-launch-faster-and-scale-smarter-2mp3</guid>
      <description>&lt;p&gt;PHP has been declared dead approximately once a year since 2010. It’s still powering around 77% of the web.&lt;/p&gt;

&lt;p&gt;At some point, that stops being a coincidence and starts being a signal worth paying attention to.&lt;/p&gt;

&lt;p&gt;The language keeps outlasting its obituaries for a reason that’s easy to miss if you’re evaluating technology purely on hype cycles: PHP solves the problems that actually kill early-stage products. Getting something built quickly. Deploying it without a two-week environment setup. Changing direction when the first version teaches you something the planning phase didn’t. These sound like baseline expectations. They’re not — most stacks make at least one of them harder than it should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Getting from idea to deployed product is where most timelines blow up. PHP’s syntax, ecosystem, and hosting compatibility all push in the same direction — toward shorter cycles, not longer ones.&lt;/p&gt;

&lt;p&gt;Open source means the libraries exist. Payment processing, authentication, file handling, email — solved, packaged, maintained by people who aren’t you. That’s time back.&lt;/p&gt;

&lt;p&gt;AWS, Google Cloud, Azure — PHP frameworks connect to all of them. Scaling infrastructure doesn’t mean switching stacks.&lt;/p&gt;

&lt;p&gt;The PHP community ships security patches fast and consistently. That ongoing maintenance backstop matters more over a three-year engagement than it does in a demo.&lt;/p&gt;

&lt;p&gt;Developer availability is real. The PHP talent pool is deep globally, which affects both hiring timelines and rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why is PHP Website Solution Development Ideal for Fast Launches?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Three specific things make PHP fast to launch with. Not in the abstract — concretely, in the ways that actually slow projects down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Rapid Web Solution Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PHP’s syntax is readable. That sounds minor. It isn’t.&lt;/p&gt;

&lt;p&gt;On any project with more than one developer — which is most projects — code that’s hard to follow slows everything down. Every review takes longer. Every new team member needs more onboarding time. Every debugging session starts with ten minutes of orientation before any actual debugging happens. PHP’s clarity keeps those costs low across the entire project timeline, not just during the initial sprint.&lt;/p&gt;

&lt;p&gt;Then there’s the documentation. PHP has been around since 1994. The community has answered nearly every question that gets asked. Pre-built modules exist for almost everything a standard web application needs — authentication flows, image processing, data export, third-party API connections. You’re building on top of solved problems rather than solving them fresh each time.&lt;/p&gt;

&lt;p&gt;For startups building an MVP, this compounds fast. The gap between “we have a validated idea” and “we have something real users can test” is where momentum dies. PHP keeps that window short. Not by magic — by removing friction at every step between concept and deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Open Source with Extensive Library Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No licensing costs. That’s the obvious benefit and the smaller one.&lt;/p&gt;

&lt;p&gt;The real upside is Composer — PHP’s package manager — and the ecosystem sitting behind it. Thousands of libraries. Payment integration that someone else spent months getting right. Authentication systems with security already baked in. Full CMS frameworks if you’re building content-heavy. E-commerce foundations if you’re building a store.&lt;/p&gt;

&lt;p&gt;Development teams that use this properly spend most of their time on whatever makes their product different. The infrastructure, the plumbing, the standard functionality that every web app needs — that gets pulled in from packages rather than built from scratch. That’s the actual mechanism behind “faster development.” Not typing faster. Writing less.&lt;/p&gt;

&lt;p&gt;Laravel and Symfony formalize this further. They’re not just libraries — they’re opinionated frameworks that make months of architecture decisions for you in exchange for following their conventions. For most projects, those conventions are exactly right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Flexible and Compatible with Most Hosting Services&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PHP runs on virtually everything.&lt;/p&gt;

&lt;p&gt;Shared hosting, VPS, managed cloud, containerized deployments — pick any of them, and PHP works without significant reconfiguration. Database compatibility is the same story: MySQL, PostgreSQL, MongoDB, SQLite. The team can start building immediately rather than spending the first week sorting out whether the chosen stack actually runs on the chosen infrastructure.&lt;/p&gt;

&lt;p&gt;This compatibility matters most at the edges of a project — at the very start when you're setting up, and at deployment when you're trying to ship. Both phases tend to surface unexpected environmental issues that eat up days. PHP's broad compatibility reduces how often those surprises happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Does PHP Help You Scale Smarter?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Fast launch means nothing if the architecture breaks the first time you double your users. This is where bad early technology decisions surface, and where PHP — built properly — holds up.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;1. Modular Architecture for Future Growth&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
MVC frameworks push you toward structure from day one. Business logic in one place. Data access in another. Presentation separate from both. Each layer can be updated without touching the others — which means adding features later doesn't require understanding and modifying everything that already exists.&lt;/p&gt;

&lt;p&gt;In practice, new payment gateway integration doesn't require touching the user authentication code. A new notification system plugs in without rebuilding the core. Third-party analytics tools connect at the application layer without rewriting the data model.&lt;/p&gt;

&lt;p&gt;The honest caveat here — and it matters — is that this assumes the initial build was done with structure in mind. PHP written without discipline scales about as well as any other undisciplined codebase, which is to say it doesn't. The framework enforces some of this, but not all of it. A PHP developer who's built applications that needed to grow knows the difference between architecture that accommodates change and architecture that resists it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Cloud Integration and Load Balancing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern PHP frameworks integrate cleanly with AWS, Google Cloud, and Azure. Not as an afterthought — this has been a deliberate framework priority as cloud became the default infrastructure choice.&lt;/p&gt;

&lt;p&gt;What that means when traffic spikes: you're not scrambling to migrate to an environment that can handle it. Load balancing, auto-scaling, managed databases — all accessible from a PHP stack without changing the application layer. The infrastructure scales; the codebase doesn't need to be rewritten to let it.&lt;/p&gt;

&lt;p&gt;For any product where traffic is hard to predict — launches, press coverage, seasonal spikes — building this elasticity in from the start is considerably cheaper than retrofitting it after the first time something falls over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Continuous Updates and Security Patches&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PHP 8.x wasn't a cosmetic release. JIT compilation brought real performance gains. The type system got meaningfully stricter. Error handling improved. The language moved forward, and the frameworks built on it moved with it.&lt;/p&gt;

&lt;p&gt;Security patches come fast, and the community disseminates them well. For teams without dedicated security staff — which is most teams at early and mid stages — that active maintenance backstop matters. You're not solely responsible for tracking every vulnerability and issuing every patch. A large, engaged community is doing significant work on that problem continuously.&lt;/p&gt;

&lt;p&gt;Over a multi-year product lifecycle, this matters more than it does in the initial evaluation. The question isn't just "what can this language do today" — it's "what will maintaining this look like in three years." PHP has a clear answer to that question.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Choosing the Right PHP Application Development Service Providers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The technology is only the starting point. PHP is capable of powering everything from a simple marketing site to a complex multi-tenant SaaS platform — but the architecture, code quality, and long-term maintainability all live with whoever builds it.&lt;/p&gt;

&lt;p&gt;What actually differentiates good PHP development partners from average ones isn't the tech stack. It's these:&lt;/p&gt;

&lt;p&gt;Industry experience, not just PHP experience. A team that's built SaaS platforms before knows what breaks at scale before it breaks. A team that's built eCommerce knows where payment integration gets complicated before it gets complicated. Generic PHP competence is a floor, not a ceiling.&lt;/p&gt;

&lt;p&gt;Honesty about technical debt. Every project accumulates some. The question is whether the team tracks it, flags it, and plans to address it — or lets it compound silently until it becomes someone else's problem at handoff.&lt;/p&gt;

&lt;p&gt;What happens after launch? The most expensive bugs appear in production. A partner who treats delivery as the end of the engagement is a different thing entirely from one who treats post-launch as part of the responsibility.&lt;/p&gt;

&lt;p&gt;Whether you're building a SaaS product, an eCommerce platform, or internal tooling with real complexity — the process needs to match the actual requirements. A generic template applied to a specific problem is how projects end up needing rewrites.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Ready to Get Started with Application Using PHP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;PHP isn't the right choice for everything. Real-time applications with heavy concurrency often make more sense in Node.js. Data-heavy pipelines lean toward Python. Picking a language because it's familiar rather than because it fits the problem is how technical debt starts.&lt;/p&gt;

&lt;p&gt;But for the majority of web products — ones that need to ship quickly, handle real traffic, integrate with modern cloud infrastructure, and grow without forcing a rewrite PHP remains one of the most practical and battle-tested options going. The 77% of the web running on it got there because the language delivers, not because nobody's evaluated the alternatives.&lt;/p&gt;

&lt;p&gt;If you want a straight read on whether PHP fits your specific build, Innostax's team has enough experience on both sides of that decision to give you an honest answer rather than a recommendation shaped by what we happen to be selling.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014 and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/how-php-web-development-can-help-you-launch-faster-and-scale-smarter" rel="noopener noreferrer"&gt;How Can PHP Development Help You Launch Faster and Scale Smarter?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Top 8 Software Development Companies in the UK</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Tue, 07 Jul 2026 04:56:37 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/top-8-software-development-companies-in-the-uk-22l6</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/top-8-software-development-companies-in-the-uk-22l6</guid>
      <description>&lt;p&gt;Picking a software development partner in the UK shouldn’t be this hard. And yet, there are hundreds of agencies, boutique studios, and large consultancies spread across London, Manchester, Edinburgh, Bristol, and every other city that’s decided it wants a tech scene. Most of them say the same things. Agile delivery. Client-centric approach. Transparent communication. The websites blend after a while.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what actually separates the good ones?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Track record in your specific industry. Whether they’ve dealt with the kind of regulatory environment you work in. How they actually handle a project when the requirements shift halfway through, because they always do. And honestly, whether they answer emails like a human being or through a ticketing system that makes you feel like a support case.&lt;/p&gt;

&lt;p&gt;This list looks at eight companies that clear those bars in different ways. Not all of them are right for everyone. Some are built for regulated industries where compliance isn’t optional. Some are genuinely great for startups that need to move fast and can’t afford to wait six weeks for a discovery phase. The table below gives a quick overview; everything after it goes deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Industry knowledge matters more than headcount. A firm that’s built software for NHS-adjacent clients three times will understand the constraints faster than one that hasn’t, full stop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Agile” means different things to different agencies. Sprint-based delivery, genuine flexibility on requirements, quick turnarounds on feedback ask specifically which of those they do, not just whether they “practice agile.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UK-based or nearshore-to-UK matters for communication. Not because offshore teams can’t do the work, but because async-only relationships slow things down in ways that compound over a long engagement.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;8 Best Software Development Companies in the UK&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Innostax | Best for Agile and Cost-Effective Solutions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Innostax was founded in 2014, and the thing that shows up consistently across their client reviews is speed, not at the expense of quality, but actual delivery velocity that moves projects forward without the usual waiting around between phases.&lt;/p&gt;

&lt;p&gt;The model is end-to-end: requirements, design, development, testing, launch, and post-launch maintenance are all handled in-house. That matters because the handoff points between phases are where most projects quietly lose time. Tech stack includes React Native, Python, Node.js, .NET Core, AWS, and Azure. Clients include Intel, Travelstart, Bancstac, and Ashore — a reasonable spread of startups to enterprises.&lt;/p&gt;

&lt;p&gt;Clutch rating is 5/5. Cody Miles, founder of Ashore, put it plainly:&lt;/p&gt;

&lt;p&gt;&amp;nbsp;“Innostax increases the velocity of my team. Ashore counts on Innostax to develop frontend code elegantly and quickly.”&amp;nbsp;&lt;/p&gt;

&lt;p&gt;That’s the kind of review that actually tells you something, rather than a generic comment about professionalism.&lt;/p&gt;

&lt;p&gt;Worth knowing: Innostax also offers staff augmentation, so if you need a team embedded with yours rather than a fully managed engagement, that’s available too.&lt;/p&gt;

&lt;p&gt;Core Services: IT Strategy Consulting, Custom Software Development, Mobile App Development, MVP Development, Enterprise Software, QA &amp;amp; Testing, Rapid Prototyping&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. GoodCore Software | Best for Complex Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GoodCore has been around since 2005. That’s a long time in software, long enough that they’ve seen what happens when you skip the discovery phase and start building before the requirements are actually nailed down. They don’t do that.&lt;/p&gt;

&lt;p&gt;The process starts with a feasibility and research phase before any code gets written. Healthcare, education, and property they work across industries where the software has to actually hold up under real-world conditions, not just look good in a demo.&lt;/p&gt;

&lt;p&gt;Clutch rating: 5/5. David Williams, Head of IT at London Women’s Clinic, said their organization and transparency set them apart. Specifically, he doesn’t have to ask many questions because the team keeps him informed without prompting. That’s a detail that’s easy to underestimate until you’ve been on a project where it’s absent.&lt;/p&gt;

&lt;p&gt;Core Services: Software Development, Team Augmentation, Digital Transformation, Product Development, Application Services&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Digiryte | Best for Building Offshore Teams&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most agencies that claim to build offshore teams are really just doing project-based outsourcing with a different name. Digiryte is one of the few that actually does what the term implies: structured, dedicated teams that integrate into the client’s own workflows rather than operating as a separate vendor.&lt;/p&gt;

&lt;p&gt;They started as a tech startup themselves, which gives them some practical empathy for what it’s like to need engineering capacity yesterday without the budget to hire full-time. Client list includes Channel 4, NHS, ARUP, and CERN, a spread that shows they can handle both the pace of media/startups and the process requirements of institutional clients.&lt;/p&gt;

&lt;p&gt;Clutch rating: 4.9/5. Yumna Akhtar from Deloitte called them “a very talented team of engineers” who “managed to turn around a complex project relatively quickly and to a high standard.” High standards and quick turnaround together are a hard combination. A lot of firms can do one.&lt;/p&gt;

&lt;p&gt;Core Services: Full Product Development, Data Engineering, Mobile &amp;amp; Web Application Development, Product Scaling, Code &amp;amp; UX Audit&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. CoreBlue | Best for Security &amp;amp; Regulated Sectors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your project touches finance, healthcare, or government, the selection criteria shift. It’s not just about whether the software works; it’s about whether it can be audited, whether it meets sector-specific compliance requirements, and whether the vendor actually understands what those requirements are before you have to explain them.&lt;/p&gt;

&lt;p&gt;CoreBlue was founded specifically for this. ISO9001, ISO27001, Cyber Essentials Plus — the certifications are there because the work demands them. The process runs through a Discovery &amp;amp; Planning phase (workshops, technical discovery meetings) before development starts. Support and scaling services carry on after launch.&lt;/p&gt;

&lt;p&gt;They’re not for everyone. If you need a quick prototype or an MVP to test an idea, they’re probably overkill. But if you’re building something that needs to hold up under a compliance audit, they’re exactly what that project needs.&lt;/p&gt;

&lt;p&gt;Clutch rating: 5/5. CoreBlue’s review from Andrea Saliu, CEO of AMA Selections:&amp;nbsp;&lt;/p&gt;

&lt;p&gt;“CoreBlue’s ability to engulf themselves in how our business works has given them a clear advantage.” The word “engulf” is doing a lot of work in that sentence it suggests genuine immersion, not surface-level onboarding.&lt;/p&gt;

&lt;p&gt;Core Services: Discovery &amp;amp; Planning, Design &amp;amp; Development, Support &amp;amp; Expand, Executive Strategy&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. AppDrawn Software Development | Best for Custom Businesses&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Twenty-plus years building business systems is a long time to have been doing one specific thing. AppDrawn has that tenure, and their work reflects it — SaaS platforms, PWAs, mobile apps, business process automation, database development. The full range of what a mid-sized business actually needs from a software partner.&lt;/p&gt;

&lt;p&gt;Their approach is consultative from the start. Business analysis before design, design before development. The upfront investment in understanding what you actually need tends to pay for itself when it prevents the expensive rework that comes from building the wrong thing well.&lt;/p&gt;

&lt;p&gt;Clutch: 5/5. The review that keeps surfacing is about their senior team’s responsiveness. Small detail — big deal on a long engagement when you need a decision made and can’t wait three days for a response from whoever manages the account.&lt;/p&gt;

&lt;p&gt;Core Services: Software &amp;amp; Mobile Development, Web Applications, AI Software, Business Process Automation, Database Development&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Cleveroad | Best for Mid-Market Long-Term UK Partnerships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cleveroad made the Clutch 1000 for 2025, specifically the top 30 out of 350,000+ companies on the platform. For context, the Clutch 1000 isn’t a self-reported award. It’s calculated from review volume, review quality, recency, and portfolio scale. 80 verified reviews at 4.9/5 is a number that takes years to build and is hard to fake.&lt;/p&gt;

&lt;p&gt;Their areas of expertise are healthcare, fintech, logistics, retail, and education technology; they specialize in sectors in which they have developed true industry expertise rather than trying to be good at everything.&lt;/p&gt;

&lt;p&gt;ISO 9001:2015 and ISO/IEC 27001:2013 compliant company; GDPR compliance built right into their development process since the very beginning at the discovery phase. The nearshore approach — British delivery leads and developers in adjacent time zones to mid-sized companies allows for both cost savings and better communications.&lt;/p&gt;

&lt;p&gt;UK projects in their portfolio include a subscription-based drinks application for London pubs as well as a telemedicine system. It demonstrates a willingness to try out various ways of collaborating.&lt;/p&gt;

&lt;p&gt;Primary Services: Custom Web/Mobile Development, AI/ML Solutions, Dedicated Software Development Teams, Backend Development, Cross-Platform Development (React Native, Flutter).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Tech Alchemy | Best for AI Products, Blockchain &amp;amp; Fintech Startups&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shoreditch-based, founded in 2016, 135 engineers, 5/5 across 33 Clutch reviews with 100% positive feedback. The numbers are good, but what actually makes Tech Alchemy interesting is the niche they’ve carved out.&lt;/p&gt;

&lt;p&gt;AI-integrated product builds, blockchain, fintech- these are sectors where technical depth and regulatory awareness need to coexist. Getting one without the other is common. Getting both is harder. Their integration partner list (LexisNexis, PayPal, AWS, Currency Cloud, Fireblocks) isn’t the kind of thing you assemble through generic web development work. It reflects experience in regulated, high-stakes environments.&lt;/p&gt;

&lt;p&gt;Products featured by Apple, BBC, and Forbes. Multiple startups raised over £100 million after working with them on MVPs. The Clutch 100 fastest-growing companies recognition is there too. If you’re building something at the intersection of finance and technology or anything where the compliance angle matters as much as the product angle, they’re worth a serious conversation.&lt;/p&gt;

&lt;p&gt;Core Services: AI Product Development, Blockchain Engineering, Fintech Solutions, MVP &amp;amp; Rapid Prototyping, Custom Software&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Softwire | Best for Enterprise &amp;amp; Public Sector Bespoke Work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Softwire came out of Cambridge and has built a long track record on technically rigorous, bespoke work for enterprise and public sector clients. Not the cheapest option here. Not trying to be.&lt;/p&gt;

&lt;p&gt;For complex, high-stakes engagements where technical quality is genuinely non-negotiable, not just a line in the brief, they have a record that stands up. The public sector experience in particular means they understand procurement processes, security requirements, and the kind of organizational constraints that trip up agencies more accustomed to startup timelines.&lt;/p&gt;

&lt;p&gt;lutch rating: 4.9/5.&lt;/p&gt;

&lt;p&gt;Core Services: Bespoke Software Development, Digital Transformation, Enterprise Applications, Public Sector Technology&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Choose&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Eight companies. Genuinely different strengths. The decision actually comes down to three questions — not the ones agencies put in their sales decks, but the ones that determine whether a partnership works.&lt;/p&gt;

&lt;p&gt;What’s your industry? Regulated sectors healthcare, finance, government need a partner that’s been there before. CoreBlue and Cleveroad have compliance built into their process. Tech Alchemy has the fintech-specific depth. Going with a generalist agency because they’re cheaper will cost more later.&lt;/p&gt;

&lt;p&gt;What stage are you at? Early stage and moving fast, Innostax or Digiryte. Established business with complex requirements and no appetite for expensive rework, GoodCore or AppDrawn. Enterprise or public sector with long procurement timelines — Softwire.&lt;/p&gt;

&lt;p&gt;How long is the engagement? A quick MVP is a different relationship than a multi-year product partnership. Most of the firms on this list are better at the latter. If you need something turned around fast and handed off, be upfront about that in conversations.&lt;/p&gt;

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

&lt;p&gt;The selection of a software development company in the United Kingdom necessitates the need to evaluate different elements. With an understanding of what you need, evaluating the knowledge of the software developers, their approach towards development, as well as their openness to communication and security, you are bound to have a fruitful relationship.&lt;/p&gt;

&lt;p&gt;Innostax will offer you a combination of competence and a drive for innovation. Your software will definitely be able to handle any challenges presented by time and growth in business through the use of their expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014 and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/software-development-companies-in-uk/" rel="noopener noreferrer"&gt;Top 8 Software Development Companies in the UK&lt;/a&gt;&lt;/p&gt;

</description>
      <category>software</category>
      <category>programming</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>React Query: Managing Asynchronous Data Rendering Guide</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Mon, 06 Jul 2026 04:38:08 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/react-query-managing-asynchronous-data-rendering-guide-2gp2</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/react-query-managing-asynchronous-data-rendering-guide-2gp2</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;React Query handles fetching, caching, and background sync so you don’t have to. Less boilerplate, fewer bugs, same data just managed properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The caching alone is worth it. Data appears instantly from cache; re-fetches quietly in the background. Users see speed. You write less code. Good deal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has a learning curve. Not steep, but real. Budget a day or two before your team moves fast.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the ever-shifting landscape of React development, handling asynchronous data can often feel like too much for a project. From data fetching to caching and state management, it’s easy to find yourself confused in a web of complexity. But fear not, my fellow developers, React Query is here for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what exactly is React Query?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Query is a robust library, offering a breath of fresh air for data fetching, caching, and state management within React applications. Serving as a central hub, it automates these processes, enabling you to craft delightful user experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What are the reasons that you should use React Query?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Streamlined Data Fetching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Query replaces the whole ritual. Loading state, error state, the fetch itself, automatic re-fetch on window focus, retry on failure, one hook. The mental model shift is small. The code reduction is not.&lt;/p&gt;

&lt;p&gt;What’s less obvious until you’ve used it for a while: consistency. Every developer on the team writes data fetching in the same way. There’s no “oh, this component does it differently” when you’re debugging at 11 pm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Intelligent Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the part that surprises people.&lt;/p&gt;

&lt;p&gt;Navigate away from a page, come back, and the data is there, no spinner, no blank flash. React Query serves the cached version immediately while it checks in the background for updates. If the data changed, it swaps in the new version quietly. If it didn’t, nothing happens. Users experience it as speed. You experience it as not having to build any of that logic yourself.&lt;/p&gt;

&lt;p&gt;Stale time is configurable. Data that barely changes? Long stale time, almost no repeat requests. Data that needs to be fresh every time? Stale time of zero. The default sits somewhere reasonable in between, which covers most cases without touching anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Simplified State Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There’s a distinction worth making here, one that took me longer than I’d like to admit to internalize properly.&lt;/p&gt;

&lt;p&gt;Server state and client state are different problems. Client state: synchronous, local, you own it entirely, it does what you tell it. Server state: async, potentially stale, shared across components, needs to be synchronized with something outside your app. Most complexity in React data management comes from treating these as the same thing and shoving both into Redux.&lt;/p&gt;

&lt;p&gt;React Query handles server state. Whatever you’re using for client state Zustand, Context, plain use State suddenly has a much smaller job. That’s not marketing, it’s just what happens when you stop managing async state manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Error Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every query exposes is Error and error. That’s the whole API surface for errors. No try-catch in use Effects, no forgetting to clear the error state before a retry, no one-off error handling patterns per component.&lt;/p&gt;

&lt;p&gt;The retry behavior ships with sensible defaults: three retries with exponential backoff. Transient network failures resolve themselves before users even notice. You can override any of it, but you usually won’t need to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Optimistic Updates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Clicked a like button and waited for the API to confirm before the count changed? That’s not how any of the app's users actually behave.&lt;/p&gt;

&lt;p&gt;Optimistic updates let you update the UI immediately, assume the request succeeds, and roll back automatically if it doesn’t. React Query handles the rollback. The setup is a bit more involved than a basic query; you’re working with use Mutation and on Mutate callbacks, but the interaction quality difference is immediately obvious. Things feel instant. That’s worth something.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Explore Data Navigation with React Query&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;npm install @tanstack/react-query&lt;/p&gt;

&lt;p&gt;One thing that catches people: the package moved to @tanstack/react-query in v4. If you’re reading a tutorial that imports from react-query (no scope), it’s on the old version. The concepts transfer, but some APIs have changed. Worth knowing before you spend time wondering why something doesn’t work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Basic Usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The query Key array is how React Query tracks and caches this request. For every variable the query depends on, the user Id here needs to be in that array. Leave something out, and you get stale data that doesn’t update when it should. That’s the single most common mistake with the library. Include everything the fetch depends on.&lt;/p&gt;

&lt;p&gt;The queryFn is just a promise. Fetch, axios, ky doesn’t matter what HTTP client you’re using.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Advantages and Considerations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Boilerplate just disappears. The loading/error/data triple that lives in every data-fetching component collapses to a single hook. Across a codebase of any size, this is a noticeable difference.&lt;/p&gt;

&lt;p&gt;Caching without configuration. You don’t set it up per query. It works out of the box, with defaults that are sensible for most use cases.&lt;/p&gt;

&lt;p&gt;The DevTools are genuinely good. Install @tanstack/react-query-devtools, and you get a panel showing every active query, its cache state, last fetch time, and status. Debugging async data goes from painful to actually manageable. This one feature alone has saved hours on more than one project.&lt;/p&gt;

&lt;p&gt;Team consistency. When there’s one right way to fetch data, code review stops catching “you handled loading state differently than the last three components.” That’s a real time saver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The basics are fast to learn. The advanced stuff isn’t. useQuery clicks immediately. Pagination with useInfiniteQuery, dependent queries, optimistic updates with proper rollback, query invalidation strategies, these require real study. Factor that into onboarding new team members.&lt;/p&gt;

&lt;p&gt;It’s a dependency. React Query is well-maintained, but it’s still an external library with its own upgrade path and breaking changes. v4 had some. v5 had more. Long-lived projects need to account for this.&lt;/p&gt;

&lt;p&gt;Some things stay hidden. React Query does a lot quietly: background refetches, garbage collection, and cache invalidation. For developers who want to reason precisely about what network requests are happening and when, this can be disorienting at first. The DevTools help. Reading the docs on cache behavior helps more.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Last Thought&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;React Query doesn’t solve everything. Form state, local UI interactions, and global app state still need their own approaches. But for the specific, messy problem of managing server state in React, it’s the most practical solution I’ve worked with. Less code, fewer bugs in the data layer, and performance characteristics that improve without extra effort.&lt;/p&gt;

&lt;p&gt;The before/after is most obvious when you’re migrating an existing component. Delete the useEffect, delete the three useState calls, replace it with useQuery, and then stare at how much shorter the file is. That moment makes the case better than any documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/react-query-managing-asynchronous-data-rendering-guide/" rel="noopener noreferrer"&gt;React Query: Managing Asynchronous Data Rendering Guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Deep Dive into Shopify’s Global Objects in Liquid</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Fri, 03 Jul 2026 05:18:06 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/deep-dive-into-shopifys-global-objects-in-liquid-4p5e</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/deep-dive-into-shopifys-global-objects-in-liquid-4p5e</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Global objects are just there — every Liquid file, zero setup, no imports needed. Cart state, customer info, product details, store settings — it’s all sitting there waiting. Once you know what’s available and where it lives, you stop wasting an hour in the docs every single time.&lt;/p&gt;

&lt;p&gt;The real magic is in combining objects. Customer plus cart unlocks personalization. Product plus metafields lets you store custom data that the default schema never even thought about. Knowing which combos work is honestly the difference between a basic theme and one that actually impresses people.&lt;/p&gt;

&lt;p&gt;Liquid is a templating language, full stop. Heavy lifting, complex filtering, anything that needs actual computation — that’s JavaScript’s job. Use global objects for what they were built for, and your themes don’t become nightmares to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Are Shopify Global Objects?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Global objects are predefined Liquid variables that Shopify automatically makes available across every template file. They hold structured data about the current store — products, collections, customers, cart contents, blog posts, navigation menus, URLs, and store settings. You don’t initialize them. Nothing to import. They’re just there the moment a Liquid file renders.&lt;/p&gt;

&lt;p&gt;That’s literally what “global” means here.&lt;/p&gt;

&lt;p&gt;The catch — and this one burns people, including me — is that some of these objects only carry meaningful data in specific template contexts. The product object is only populated when you’re actually on a product page. The checkout object only makes sense inside the checkout template. Use either of them somewhere else, and you don’t get an error. You get empty output. Which looks exactly like a typo in your property name. Which takes forever to track down because there’s nothing helpful to go on.&lt;/p&gt;

&lt;p&gt;Knowing what’s available where matters just as much as knowing the properties themselves. I can’t stress that enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Categories of Global Objects&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Store Information&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These carry store-level metadata — stuff that stays consistent no matter what page a customer lands on or what they’re looking at.&lt;/p&gt;

&lt;p&gt;The shop is the one you’ll reach for all the time. Store name, domain, email, currency, description, phone number, localization settings — all of it lives here. Any time you need to reference the store itself rather than a specific product or customer, the shop is your starting point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Welcome to {{ shop.name }}!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Your currency is set to {{ shop.currency }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Settings pull directly from the theme customization panel — Online Store &amp;gt; Customize in Shopify admin. This is how merchant-configurable values get into templates without hardcoding anything. Colors, fonts, contact emails, feature toggles. Expose them as settings, and merchants can update things themselves without ever touching code. Build themes this way, and you stop getting support tickets every time someone wants to change their contact email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Support Email: {{ settings.contact_email }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Customer and User Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These deal with authenticated customer sessions. They’re essentially useless when nobody’s logged in.&lt;/p&gt;

&lt;p&gt;The customer is the main object here. First name, last name, email, order history, saved addresses, tags — all in there. The very first thing you almost always do with this object is check whether it actually exists before you try to read any properties off it. Guest sessions return nothing, and accessing properties on a nil customer doesn’t throw an error. It just gives you blank output. Which is confusing. Which wastes time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% if customer %}
  &amp;lt;p&amp;gt;Welcome back, {{ customer.first_name }}!&amp;lt;/p&amp;gt;
{% else %}
  &amp;lt;p&amp;gt;Please log in to view your account details.&amp;lt;/p&amp;gt;
{% endif %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;customer.orders gives you the full order history for whoever’s logged in. This one’s only accessible inside customer account templates, by the way. Trying to use it in a homepage section won’t work the way you’d expect. If you’re building a custom account dashboard — and a lot of clients want one — this is what your order list runs through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Product and Collection Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Probably the objects you spend the most time with in everyday Shopify work.&lt;/p&gt;

&lt;p&gt;The product represents a single product and is only available on product template pages. Everything about that product is here — title, description, price, vendor, images, variants, metafields, tags. The variants array is especially important because that’s where sizes, colors, and other options live as separate objects, each carrying its own price, SKU, inventory count, and availability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;{{ product.title }}&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;Price: {{ product.price | money }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;collection is for, well, collections of products. Available on collection template pages. Gives you the collection title, description, image, and the array of products. Looping through the collection. products is the standard pattern for any collection page layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;{{ collection.title }}&amp;lt;/h1&amp;gt;
&amp;lt;ul&amp;gt;
  {% for product in collection.products %}
    &amp;lt;li&amp;gt;{{ product.title }} - {{ product.price | money }}&amp;lt;/li&amp;gt;
  {% endfor %}
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick note worth knowing: collection. Products default to 50 products max per page. For larger collections, pagination is non-negotiable. Without it, the page silently cuts off at product 50, and customers never see anything beyond that. Nobody notices until someone asks why the store only seems to have half its inventory. Then it’s a fun conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Shopping Cart and Checkout Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cart state is relevant on almost every page, so this object shows up constantly. &lt;/p&gt;

&lt;p&gt;The cart holds the complete current cart — line items array, total item count, total price, applied discount codes, and cart attributes. Because it’s globally available, you can show an accurate item count in the header on every page without any extra setup. Which is exactly what you want — a persistent indicator that stays correct as customers add and remove things.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;Your Cart&amp;lt;/h2&amp;gt;
{% for item in cart.items %}
  &amp;lt;p&amp;gt;{{ item.product.title }} - Quantity: {{ item.quantity }}&amp;lt;/p&amp;gt;
{% endfor %}
&amp;lt;p&amp;gt;Total: {{ cart.total_price | money }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checkout gives you access to order summary data inside the checkout template. Shopify controls what you can actually customize in checkout pretty tightly, but the data that is accessible — order details, customer info, shipping address — comes through this object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Blog and Article Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More stores should use Shopify’s blogging features than actually do. For themes that need to support content marketing, these matter a lot. &amp;nbsp;&lt;/p&gt;

&lt;p&gt;blog represents a single blog within the store. A store can have multiple blogs — a news section, a recipe journal, a behind-the-scenes series — and this object gives you the title, handle, and articles array for whichever one you’re working with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;{{ blog.title }}&amp;lt;/h1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Routes generate correct URLs for standard store pages dynamically, based on the actual store structure rather than whatever you’ve hardcoded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a href="{{ routes.cart_url }}"&amp;gt;Go to Cart&amp;lt;/a&amp;gt;
&amp;lt;a href="{{ routes.account_login_url }}"&amp;gt;Log In&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hardcoding navigation paths instead of using routes is the kind of mistake that causes broken links whenever store URL structures change. It’s also the kind of bug that gets reported months after a theme ships and takes embarrassingly long to trace back to a hardcoded string buried somewhere in a template file.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Advanced Use Cases&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Using Metafields with Global Objects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Metafields let you attach custom data to products, collections, customers, and other Shopify resources — data that the default schema simply doesn’t have fields for. A product might need material composition, care instructions, country of origin, and sizing details that go beyond what Shopify natively supports. Metafields are how that data gets attached to the product object and into your templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Material: {{ product.metafields.custom.material }}&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Care Instructions: {{ product.metafields.custom.care_instructions }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Personalizing the Storefront with customer and cart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Combining customer and cart is where personalization goes from theoretical to actually useful. Greeting customers by name, showing real-time cart counts, displaying messaging that changes based on login status — all of it comes from these two objects working together.&lt;/p&gt;

&lt;p&gt;This pattern turns up everywhere in well-built themes. Header components that greet returning customers. Promotional banners that vary by account status. Checkout flows that pre-fill details for logged-in users. The combination makes all of it possible without any external data fetching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Custom Sorting and Filtering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Liquid’s sort filter applied to collection products gives you custom ordering beyond the default sort options — price, alphabetical, and creation date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% assign sorted_products = collection.products | sort: 'price' %}
{% for product in sorted_products %}
  &amp;lt;p&amp;gt;{{ product.title }} - {{ product.price | money }}&amp;lt;/p&amp;gt;
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The limitation is worth understanding before you build anything significant on top of this: Liquid-side sorting works only on products already loaded into the page. Usually, the 50-product default. You’re not sorting across the entire collection — you’re sorting within the current page. For real cross-collection filtering at any scale, you need JavaScript and the Storefront API, or an app.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tips for Working with Global Objects&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Keep the docs open. The Shopify Liquid reference is thorough and actively maintained. Global objects expose far more properties than anyone memorizes, and relying on memory for property names is how you spend 20 minutes debugging something that turns out to be a typo that renders silently as nothing.&lt;/p&gt;

&lt;p&gt;Combine objects deliberately. The most useful Liquid patterns come from combining global objects rather than using each one in isolation. Think through what data you actually need and which combination exposes it. customer plus cart for personalized experiences. product plus collection for breadcrumb navigation. shop plus settings for store-specific configurations.&lt;/p&gt;

&lt;p&gt;Use the Theme Editor for actual testing. Shopify’s preview mode renders templates with real store data. Some properties that should return something come back empty in certain contexts. The Theme Editor catches that before it hits a live store and becomes a support ticket.&lt;/p&gt;

&lt;p&gt;Take loops seriously. Nested loops — collections inside collections, products inside collections, variants inside products — compound rendering time faster than you’d expect, and are genuinely unpleasant to profile after the fact. If a loop is getting complicated, that’s usually a signal that the logic should move to JavaScript or the value should be precomputed somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Common Pitfalls&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Accessing objects outside their valid context. The product object is populated only on product pages.Know which templates each object belongs to before writing logic that depends on it.&lt;/p&gt;

&lt;p&gt;Putting too much logic in Liquid. This one comes up constantly. Liquid is built for displaying data, not processing it. The moment you’re writing deeply nested conditionals, trying to implement search in Liquid, or chaining long string manipulation sequences — stop. &lt;/p&gt;

&lt;p&gt;Chaining filters without testing each step. Liquid filters are easy to chain, and that ease makes it easy to chain too many without checking what happens in between. money, strip_html, url_encode, date — each one transforms the value, and the order matters. &lt;/p&gt;

&lt;p&gt;Forgetting empty states. Empty cart. Collection with no products. Customer with no order history. Write an explicit empty state for every list and loop you build. Every single one. No exceptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The gap between a developer who struggles in Liquid and one who moves through Shopify theme work confidently is mostly a gap in understanding global objects — what exists, where it’s available, and how to combine things.&lt;/p&gt;

&lt;p&gt;The practical advice that’s actually helped: build things, break things, use the Theme Editor constantly, and read the docs when behavior doesn’t match expectations instead of trying to logic your way to an answer. Global objects are consistent and well-documented. When something seems wrong, it’s almost always a context issue or a typo, and the docs will tell you which.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/deep-dive-into-shopifys-global-objects-in-liquid/" rel="noopener noreferrer"&gt;Deep Dive into Shopify’s Global Objects in Liquid&lt;/a&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>programming</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Designing .NET Microservices for Edge Computing in IoT and 5G</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Thu, 02 Jul 2026 05:44:02 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/designing-net-microservices-for-edge-computing-in-iot-and-5g-1c1c</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/designing-net-microservices-for-edge-computing-in-iot-and-5g-1c1c</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cloud roundtrips sound fine until you’re building something where the response window is 10 milliseconds. At that point, the architecture either works at the edge or it doesn’t work at all — there’s no middle ground to negotiate your way into.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;.NET doesn’t get enough credit for how well it actually runs on constrained edge hardware. Cross-platform, lean when you need it to be, solid container story. It’s a legitimate choice for edge deployments, not a compromise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;5G isn’t just a speed upgrade. It’s an architecture unlock. Things that were technically coherent proposals for years are finally shippable because the network stopped being the bottleneck.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction to Edge Computing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Defining Edge Computing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The simplest way I can describe edge computing is to stop asking the data to travel, and move the computation to where the data already is.&lt;/p&gt;

&lt;p&gt;Edge computing puts the computation physically close to the sensor. The reading gets processed on hardware in the same building, on the same network segment, or in some cases on the same device. The response happens in milliseconds rather than hundreds of milliseconds. And because the decision doesn’t depend on a network connection to function, the system keeps working when that connection drops — which it will, somewhere in any real-world deployment, at some point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edge Computing vs. Cloud Computing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn’t an either-or question, and framing it that way leads to bad architectural decisions in both directions.&lt;/p&gt;

&lt;p&gt;Cloud is genuinely better at certain things.  Anything where latency is acceptable, and the value of centralized visibility outweighs the cost of sending data there. Cloud handles these well and should.&lt;/p&gt;

&lt;p&gt;The real architecture work is designing the boundary between the two. What decisions live at the edge? What data travels upstream and when? What happens to the local system if cloud connectivity is unavailable for an hour? Getting those answers right is the majority of the design problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Role of Edge Computing in IoT and 5G Networks&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;IoT scale changes everything. A hundred connected devices is a manageable data flow problem. A million devices generating continuous readings is a different category of problem entirely — one where centralized processing isn’t a viable architecture regardless of how much cloud compute you throw at it.&lt;/p&gt;

&lt;p&gt;5G changes the edge architecture calculus by improving what’s possible at the connectivity layer. Sub-millisecond latency between 5G infrastructure and edge nodes. Genuine high-bandwidth connections to mobile devices. Density support for massive concurrent device counts. Remote surgery. Real-time AR at scale. Autonomous vehicle coordination at intersection density. They’re becoming real deployments because 5G finally supports them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Concepts in Distributed Systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fundamentals of Distributed Systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edge computing is a distributed systems design with the difficulty settings turned up and the escape hatches removed.&lt;/p&gt;

&lt;p&gt;Scalability at the edge usually means adding nodes rather than upgrading the ones you have — edge hardware has fixed resource ceilings, and you can’t request a larger instance type when demand spikes. Device failure rates in industrial edge deployments are meaningfully higher than cloud server failure rates, and the architecture has to assume that rather than treating it as an exceptional condition.&lt;/p&gt;

&lt;p&gt;High availability for edge applications isn’t a performance discussion. When the application is monitoring patients or managing industrial equipment or controlling infrastructure, downtime is a safety issue. That changes how seriously you take redundancy, failover, and graceful degradation — it has to be designed in from the start, not added after the first production incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Role of Microservices and Containerization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microservices address a problem that’s more acute at the edge than anywhere else: you can’t always restart everything to update something.&lt;/p&gt;

&lt;p&gt;Microservices let you update the sensor ingestion service without touching the alerting service or the local analytics service. A failure in one service stays contained rather than cascading into a full device outage.&lt;/p&gt;

&lt;p&gt;Containerization makes fleet management at scale actually possible. A .NET service containerized with Docker runs identically on your development laptop, on a Linux VM in your CI pipeline, and on an ARM-based industrial edge gateway. That consistency eliminates the class of “it worked in staging” failures that are especially painful when the production device is physically inaccessible and diagnosing the environment-specific issue requires someone to physically travel to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Overview of .NET and Its Role in Microservices&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Understanding .NET Frameworks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The .NET cross-platform story used to require some faith. It’s earned trust now. Teams running .NET services on ARM-based edge hardware in production environments aren’t working around platform-specific runtime bugs — the runtime is stable across the target platforms that real IoT deployments actually use.&lt;/p&gt;

&lt;p&gt;AOT compilation in recent .NET versions is specifically valuable for edge deployments. Startup time matters when services restart after power cycles. Memory footprint matters when the total device RAM is 512MB shared across multiple services. Modern .NET performs well on both dimensions in ways that earlier versions couldn’t reliably claim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of .NET for Distributed Systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write once, deploy across x86 edge servers, ARM embedded devices, and varied Linux distributions without maintaining separate codebases or platform-specific workarounds. Performance characteristics that actually matter when 20% excess memory consumption doesn’t evaporate into a 32GB cloud VM but instead prevents you from running all the services you need on the device.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Designing Distributed .NET Microservices for Edge Computing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Architectural Considerations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most important mindset shift for edge architecture design: start with the constraints, not the ideal system.&lt;/p&gt;

&lt;p&gt;Most architectural processes define what the system should do and determine how to make it work within operational realities. Memory and CPU ceilings don’t negotiate. &lt;/p&gt;

&lt;p&gt;Real-time requirements need to be mapped explicitly. Which operations have hard latency budgets? Can any step in those operations involve a network call? If the answer is yes and the latency budget is 10 milliseconds, the architecture is broken before implementation starts. Local execution for the critical path isn’t a performance optimization — it’s a correctness requirement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building Decentralized Microservices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Services that make synchronous calls to other services for data they need to function fail during every connectivity interruption. At the edge, connectivity interruptions are a scheduled operating condition.&lt;/p&gt;

&lt;p&gt;Data synchronization between edge nodes is genuinely the hardest part of edge architecture. Eventual consistency is the realistic model — nodes will have different views of shared data during connectivity gaps, and the system needs to handle that rather than pretending it won’t happen. Events queue locally when connectivity is unavailable and drain when it returns, without requiring the producer and consumer to be simultaneously connected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communication and Data Consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;gRPC’s binary serialization and HTTP/2 multiplexing are meaningfully more efficient than JSON over HTTP when inter-service bandwidth is limited. MQTT was designed specifically for unreliable networks and constrained devices — for device-to-gateway communication, it’s usually the right starting point unless there’s a specific reason to prefer something else.&lt;/p&gt;

&lt;p&gt;Event Sourcing transforms node synchronization from a state merging problem into a log replication problem. Log replication is well understood. State merging across independently evolving nodes is not. CRDTs let nodes update independently while disconnected and merge deterministically when they reconnect — no coordination required, no conflict resolution logic, no data loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;IoT Integration in Edge Computing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Overview of IoT Devices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real IoT deployments are messier than the diagrams suggest. Industrial vibration sensors speaking Modbus. Consumer devices using MQTT. Medical wearables have their own proprietary protocols. RFID readers, environmental monitors, IP cameras, PLCs — all generating continuous streams, all expecting the system to respond on their own timing. The edge layer’s job is absorbing that heterogeneity and producing something consistent enough for the rest of the system to work with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenges in IoT Data Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Volume at real IoT scale makes centralized raw data processing indefensible — the bandwidth cost alone is prohibitive, and the processing cost isn’t far behind. Edge filtering and aggregation turn an unmanageable data flood into a tractable event stream.&lt;/p&gt;

&lt;p&gt;Velocity is what makes real-time processing genuinely hard. For applications where a sensor reading triggers a physical response, the value of that reading decays fast. A reading actionable at 5 milliseconds is worthless at 500 if the physical situation it describes has already changed. Processing pipelines need to maintain low latency under sustained high data rates — a requirement that most application development experience doesn’t prepare you for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategies for .NET Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lean ASP.NET Core services load only the middleware they actually use. .NET-based edge gateways translate between device protocols and consistent internal formats. Local analytics that processes and acts on data before it travels anywhere — because for anomaly detection and threshold alerting, the window for meaningful action closes before a centralized analytics platform can respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5G Networks and Edge Computing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Enabling Ultra-Low Latency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;5G moves the hard boundary between “must execute locally” and “can tolerate a network hop.” Operations that previously had to run entirely on device because any network involvement exceeded the latency budget can now, for some use cases, involve a nearby edge server while still meeting their timing requirements. This expands the architecture design space in ways that weren’t available with 4G.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed Microservices in 5G Environments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Network slicing lets different traffic types use different network performance profiles — real-time control traffic on an ultra-low-latency slice, bulk data upload on a high-throughput slice, mission-critical monitoring on a reliability-optimized slice. Services that are slice-aware can route traffic appropriately rather than pushing everything across a single undifferentiated connection.&lt;/p&gt;

&lt;p&gt;Inter-node coordination that was impractical at 50ms latency becomes tractable at 1ms. Mobile device handover between edge nodes as devices move through a deployment area happens without dropping service state — a problem 5G’s architecture addresses more cleanly than previous generations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases: IoT and 5G Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Autonomous vehicles need LiDAR, camera, and radar fusion with real-time decision making that no cloud round-trip can support. V2X coordination between vehicles and infrastructure requires 5G latency and edge processing working together — neither is sufficient alone.&lt;/p&gt;

&lt;p&gt;Industrial automation brings closed-loop control to equipment that previously ran on isolated proprietary networks because general-purpose connectivity wasn’t reliable or fast enough. Smart cities process traffic management, utility monitoring, and public safety data locally for immediate decisions, sending aggregated summaries upstream for city-wide planning — the edge tier is what makes local response times possible, the cloud tier is what makes city-wide visibility possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Best Practices for Building Edge Computing Architectures with .NET&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scalability and Fault Tolerance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design for failures as routine operating conditions, not edge cases. The mental shift from “how do I prevent failures” to “how do I keep working when failures happen” is the single most important architectural mindset change for edge systems. Retry logic, Polly circuit breakers, local queuing during outages — these need to be in the initial design. Adding them later means redesigning interfaces built on reliability assumptions that production won’t honor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimizing Resource Usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alpine-based .NET container images are a fraction of the size of full Ubuntu-based ones. On cloud infrastructure the difference is irrelevant. On an edge device with limited storage over a constrained network connection, image size compounds across every service in the deployment and every update pushed to the fleet.&lt;/p&gt;

&lt;p&gt;Every dependency has a memory cost. On a 32GB cloud VM this is background noise. On a 512MB edge device shared across multiple services it’s a design constraint that needs explicit tracking from the first sprint. Cache frequently accessed data and expensive computed results locally — this simultaneously eliminates network latency for common operations and maintains functionality during connectivity interruptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing and Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Test against the conditions your services will actually encounter. tc on Linux introduces controlled packet loss, latency, and bandwidth constraints. Services that behave correctly under 5% packet loss and 50ms added latency during development behave correctly in production. Services tested only against a perfect local network announce their assumptions loudly in production at the worst possible time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Challenges and Solutions in Edge Computing for IoT and 5G&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Key Challenges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Resource limitations aren’t a problem you solve once. Every feature addition, every dependency update, every configuration change has a resource cost that needs to be evaluated against a fixed budget. Network instability isn’t exceptional — it’s a guaranteed occurrence at real deployment scale. Security is harder when devices sit in environments you don’t control, are physically accessible to unauthorized people, and may not have received software updates as promptly as data center infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Benchmark on actual target hardware early — before committing to an architecture that doesn’t fit the resource envelope of the devices you’re deploying to. Edge caching addresses both instability and latency simultaneously. TLS on all connections, certificate-based device authentication, regular credential rotation, hardware security modules where the device supports them — defaults, not options, given the physical attack surface of edge deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-World Case Studies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Smart factories running .NET microservices against equipment telemetry in real production facilities — not pilot programs, not proof-of-concept installations. Healthcare monitoring detecting clinically significant events locally and alerting immediately without any cloud dependency in the critical path. Retail analytics surfacing store-level insights in near-real-time instead of overnight batch jobs, giving operations teams information while they can still act on it, rather than reports about what happened yesterday.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Future Trends and Innovations in Edge Computing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI and Machine Learning at the Edge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Training centrally and deploying inference to edge hardware is an established practice. What’s improving is efficiency — smaller model architectures delivering acceptable accuracy within edge hardware budgets, better tooling for detecting when edge model performance has drifted, and cleaner integration between the training pipeline and the edge deployment lifecycle. .NET’s ML.NET integration makes this accessible without maintaining a separate Python inference pipeline alongside the application stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advancements in 5G&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Private 5G deployments for industrial environments are moving from early adopter to mainstream. Holographic communication — requiring the bandwidth and latency combination that only 5G provides — is transitioning from research demonstrations to early commercial deployments. The infrastructure investment cycle for 5G-connected edge nodes in public infrastructure is accelerating in cities treating modernization seriously rather than incrementally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evolving .NET Technologies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The trajectory of .NET development over the last several major versions has consistently moved toward what edge deployments need — smaller footprints, faster startup, better container optimization, improved cross-platform reliability. That trajectory isn’t slowing. Future releases will likely bring more edge-specific framework support and better tooling for managing distributed device fleets at the scale that real IoT deployments reach.&lt;/p&gt;

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

&lt;p&gt;This isn’t a future architecture pattern. Smart factories, healthcare monitoring systems, retail analytics platforms, and smart city infrastructure are running on edge-deployed .NET microservices in production right now.&lt;/p&gt;

&lt;p&gt;The constraints are physical and fixed. The network drops. The hardware ceiling doesn’t move. The latency budget is set before you write a line of code. .NET handles these constraints well — cross-platform, container-native, good performance on constrained hardware, clean integration story with IoT and cloud tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: Designing .NET Microservices for Edge Computing in IoT and 5G&lt;/p&gt;

</description>
      <category>5g</category>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Top 10 Software Development Companies Worldwide (2026)</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Wed, 01 Jul 2026 05:36:46 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/top-10-software-development-companies-worldwide-2026-2fcm</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/top-10-software-development-companies-worldwide-2026-2fcm</guid>
      <description>&lt;p&gt;The global software market is projected to reach $921 billion in 2026, growing at 11.6% annually, with worldwide IT spending on track for $6.31 trillion — the largest single-year expansion in the industry’s history. Software development is no longer just execution; it’s strategy. This guide ranks the top 10 software development companies for 2026 based on verified delivery track records, technical depth, and client outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;: AI is now a baseline, not a differentiator. The right partner depends on specialization and delivery model, not size. Top global firms deliver 40–70% cost savings over in-house teams. Mid-sized firms often outperform large vendors on speed and ownership. Strong signals: client retention, verified reviews, case studies with real numbers, and low developer attrition.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Choosing the Right Development Partner Matters More in 2026&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every company boasts agility in its delivery and the presence of senior engineers. The difference between a good and a great partner lies in how they handle ambiguity, the ability of senior engineers to stick around beyond month two, and their ability to keep communication going in case of any issues. Global software spending will reach $1.44 trillion by 2026, making it the fastest-growing segment across all of IT. Making the wrong partner choice means losing market advantage.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How We Selected These Companies&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Selections are based on six criteria: technical depth, client evidence (case studies with measurable outcomes), delivery model, industry recognition (Inc. 5000, Deloitte Fast50, ISO certifications), review quality, and global reach. No paid placements or affiliate relationships.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Quick Comparison: Top 10 Software Development Companies&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Innostax | Best for Fast, High-Quality Custom Software Solutions
**
One tech lead owns execution end-to-end. AI-native workflow catches 30–40% of issues before code is written. Four-layer code review before anything ships. Daily Loom updates and GitHub-linked invoices make every billed hour traceable. Two-week free trial, one-day exit notice, no lock-in. Great Place to Work certified (India, 2025–2026).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;2. Atomic Object&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;100% employee-owned since 2001. Test-driven development and paired programming are standard, not upsells. Covers web, mobile, desktop, and embedded/IoT. Notable clients include Ford Motor Company and Eaton Corporation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. BairesDev&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;4,000+ engineers across 50+ countries. Fewer than 1% of applicants pass their vetting. Clients include Google, Pinterest, and Rolls-Royce. Engineers integrate into existing teams fast, with no extended onboarding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cleveroad&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ISO 9001 and ISO 27001 certified. AWS Select Tier Partner. Full-cycle development with a defined focus on healthcare and logistics. Clients include HSBC and Virgin Atlantic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. AgileEngine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perfect 5.0 rating, nine consecutive years on the Inc. 5000. Teams integrate without requiring client environments to reshape themselves. Time-zone coverage across the Americas and Eastern Europe. Clients include Bloomberg, Motorola, and Uber.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Geniusee&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Specializes in AI, data engineering, and cloud-native systems — not a generalist shop that added AI to a service list. Best suited for fintech, analytics platforms, and intelligent applications where data architecture matters from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Merixstudio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;26 years of continuous operation. Offices in Poznań, New York, Bristol, and Berlin. Notable clients include Volkswagen, Toshiba, and HSBC. Institutional depth that newer firms cannot replicate.&lt;br&gt;
**&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Miquido**&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Deloitte Technology Fast 50, Google Certified Agency. 90% of new projects come from existing client referrals — the clearest signal of post-delivery satisfaction. Production ML track record across Aviva, Skyscanner, and Dolby Laboratories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Simform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dedicated team model for SaaS and product engineering. Cloud-native architecture, solid DevOps, continuous agile delivery. Notable clients include Red Bull, Sony Music, and Marriott.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Future Processing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;25 years of operation, Microsoft Gold Partner since 2007. Built for long-horizon engagements. One published outcome: a payment portal rebuilt from 50% to 95% conversion rate.&lt;/p&gt;

&lt;p&gt;What’s Driving the Software Development Market in 2026&lt;/p&gt;

&lt;p&gt;AI is Embedded in Delivery, Not Just in Products&lt;/p&gt;

&lt;p&gt;The right question for any vendor isn’t “can you build AI products?” It’s “how does AI show up in your delivery workflow?” Plan-first development, AI-assisted code review, and LLM-augmented architecture decisions separate firms that are ahead from those keeping up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Spend is Growing Faster Than Any Other IT Category&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Global software spending reached $1.44 trillion in 2026, growing at 15.1% — revised upward by Gartner three times within a single year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team Stability Has Become a Procurement Criterion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developer attrition is the most commonly cited cause of outsourcing failure. Buyers are now explicitly asking for attrition rates and tenure data before signing contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-Term Engineering Partnerships Over One-Off Project Delivery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The market has shifted away from project-based outsourcing toward firms that own outcomes across the full product lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Factors When Choosing a Software Development Company&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ask: who specifically builds the product, what the development process looks like, whether they can provide named references in your industry, what developer attrition looks like, how communication works day-to-day, what post-launch support includes, and how scope changes are handled.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of Working with a Global Software Development Agency&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cost Efficiency Without Quality Trade-offs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;40–70% savings versus equivalent in-house teams without sacrificing quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-Demand Access to Deep Specialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Faster and cheaper than building AI, cloud, or data engineering capability internally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faster Time to Market&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pre-built frameworks and streamlined delivery processes compress timelines. Faster MVP cycles are a direct competitive advantage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalability on Demand&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Engineering teams scale up for intensive phases and back down during maintenance — flexibility in-house teams can’t match.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The ten companies here represent different strengths and fits. Atomic Object for US-based engineering quality. BairesDev and AgileEngine for scaling fast with pre-vetted talent. Cleveroad and Geniusee for regulated-industry delivery. Miquido for AI-native mobile. Future Processing for long-horizon cloud and data transformation. And Innostax for founders and CTOs who want a managed team that owns outcomes, with daily transparency, a two-week free trial, and no lock-in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/software-development-companies/" rel="noopener noreferrer"&gt;Top 10 Software Development Companies Worldwide (2026)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Frequently Asked Questions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What services do top firms offer?&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Full lifecycle delivery — custom software, AI, cloud, DevOps, staff augmentation, MVP, and QA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I compare companies?&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
Start with case studies showing real outcomes, then review quality, attrition rates, and named references in your domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is custom software development?&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Software built for specific business needs using agile processes — reduces technical debt and scales better than off-the-shelf tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best engagement model for an MVP?&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
Time-and-materials or dedicated team. Fixed-price contracts for MVPs usually end in scope disputes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do top firms use AI in 2026?&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
Inside their delivery process — code review, testing, architecture decisions — not just as a client-facing feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Onshore vs. nearshore vs. offshore?&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Onshore = proximity at premium cost. Nearshore = time-zone overlap with savings. Offshore = 40–70% savings with senior talent from India or Eastern Europe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flags when evaluating vendors?&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Vague attrition data, no named references, weak communication SLAs, case studies with no measurable outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should a contract include?&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Scope, milestones, pricing, IP ownership, SLAs, attrition protections, change request processes, post-launch support, and exit clauses.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Dockerized Lambda: Transform Your Development with Efficiency</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Tue, 30 Jun 2026 06:01:34 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/dockerized-lambda-transform-your-development-with-efficiency-4e70</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/dockerized-lambda-transform-your-development-with-efficiency-4e70</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Enhanced Development Efficiency&lt;/strong&gt;: Most developers don’t realize how much time gets wasted chasing bugs that only show up in production. Dockerizing your Lambda functions lets you run the same environment on your laptop that runs on AWS — which means what you test locally is genuinely what ships. Faster cycles, less guesswork, more control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versatile Integration&lt;/strong&gt;: This isn’t a niche solution built for one type of project. Healthcare platforms, fintech products, mobile backends, QA pipelines — Dockerized Lambda slots into all of it without friction. The foundation it creates is consistent enough to hold up across very different development contexts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Flexibility and Security&lt;/strong&gt;: When your Lambda code lives inside a Docker container, you’re not just getting portability — you’re getting a locked, reproducible environment. That consistency directly translates into better security posture and way less “it worked yesterday” energy from your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Dockerized Lambda function is a technique that involves packaging serverless applications into Docker containers, granting developers more control over the execution environment.&lt;/p&gt;

&lt;p&gt;Lambda functions, typically executed on managed infrastructure like AWS Lambda, find enhanced flexibility through Dockerization. This technique is particularly beneficial for healthcare custom software development and cross-platform mobile app development services — environments where a gap between dev and prod isn’t just inconvenient, it erodes trust in the entire system.&lt;/p&gt;

&lt;p&gt;Furthermore, Dockerizing Lambda functions facilitates QA software testing services and supports Android app development companies and iOS development services. It empowers banking software development companies and custom enterprise software development by offering a consistent environment for development and deployment — one that doesn’t shift depending on who’s running the code or where.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Planning to Create Dockerized Lambda&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Creating application files and a Dockerfile within them&lt;/li&gt;
&lt;li&gt;Creating ECR, and Building docker image, and pushing it to ECR&lt;/li&gt;
&lt;li&gt;Creating a Lambda function through an ECR Image&lt;/li&gt;
&lt;li&gt;Creating triggers for Lambda in the form of APIs through AWS API Gateway&lt;/li&gt;
&lt;li&gt;Deploy the APIs and test the APIs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1 : Creating Application Files and Dockerfile Within It&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Create the index.js file with the struct of a lambda and leverage the event object to get path, protocol, and type of API (POST, GET, PATCH, DELETE).&lt;/p&gt;

&lt;p&gt;Create Dockerfile - the files to be copied will be kept in the directory /var/task/ as the AWS Lambda expects them to be there. Here is a sample of the Docker file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; public.ecr.aws/lambda/nodejs:14&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; index.js package.json package-lock.json /var/task/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; &amp;amp;#91;"index.handler"]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the index.js file. Here we are using DynamoDB for CRUD in order to avoid DB connection logic for SQL DB and focus on architectural steps.&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;AWS&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="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ap-south-1&lt;/span&gt;&lt;span class="dl"&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;dynamodb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DynamoDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DocumentClient&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;dynamodbTableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;product-inventory&lt;/span&gt;&lt;span class="dl"&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;healthPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/health&lt;/span&gt;&lt;span class="dl"&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;productPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/product&lt;/span&gt;&lt;span class="dl"&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;productsPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request event: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&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;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;healthPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;productPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;productsPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getProducts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;productPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;saveProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PATCH&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;productPath&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;requestBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;modifyProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;productPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deleteProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;404 Not Found&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productId&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dynamodbTableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;productId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;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;return&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Item&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Do your custom error handling here. I am just gonna log it: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProducts&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dynamodbTableName&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;allProducts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;scanDynamoRecords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;91&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;allProducts&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scanDynamoRecords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scanParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;dynamoData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scanParams&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;itemArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dynamoData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Items&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;dynamoData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LastEvaluatedKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;scanParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExclusiveStartkey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dynamoData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LastEvaluatedKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;scanDynamoRecords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scanParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemArray&lt;/span&gt;&lt;span class="p"&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;itemArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Do your custom error handling here. I am just gonna log it: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestBody&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dynamodbTableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;requestBody&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SAVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;requestBody&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Do your custom error handling here. I am just gonna log it: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;modifyProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateValue&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dynamodbTableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;productId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;UpdateExpression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`set &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;updateKey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = :value`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ExpressionAttributeValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updateValue&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;ReturnValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UPDATED_NEW&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UPDATE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;UpdatedAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Do your custom error handling here. I am just gonna log it: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deleteProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productId&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dynamodbTableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;productId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;ReturnValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ALL_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;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Do your custom error handling here. I am just gonna log it: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;apiError&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Might be issue with DB connection JUST TESTING&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;buildResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statusCode&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="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;body&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorObj&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&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="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;Generate package.json and package-lock.json and locally create a docker image and run it over a container to make sure everything works fine.&lt;/p&gt;

&lt;p&gt;Worth saying this plainly — don’t skip the local container test. Run it, hit the endpoints, and confirm the DynamoDB calls return what you expect. A bug caught here costs you ten minutes. The same bug caught after you’ve pushed to ECR and wired up Lambda costs you an afternoon.&lt;/p&gt;

&lt;p&gt;Now we have our files ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Creating an ECR Instance&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;ECR or Elastic Container Registry is a service provided by AWS to keep Docker images in the repo and use them as per demand. We will be using these images to create our lambda.&lt;/p&gt;

&lt;p&gt;Think of ECR as a private Docker Hub that lives inside your AWS account. It stores your image, versions it, and hands it to Lambda whenever the function spins up. Clean, integrated, no third-party registry needed.&lt;/p&gt;

&lt;p&gt;Search ECR in AWS and click on “Create Repository.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give a name to the repository and click “Create Repository.”&lt;/li&gt;
&lt;li&gt;The created Repo on ECR will be shown in the list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now go to the repo, and you will find the “push commands”. Go through the highlighted/marked buttons as below.&lt;/p&gt;

&lt;p&gt;These commands we need to execute when pushing the Docker image to our created repo at ECR.&lt;/p&gt;

&lt;p&gt;You can follow the image below to check how files are uploaded to the EC2 and then how the Docker image is created.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RED LINE: Creating a file in the directory&lt;/li&gt;
&lt;li&gt;BLUE LINE: Writing content in the files&lt;/li&gt;
&lt;li&gt;YELLOW LINE: Executing the first push command we got from ECR. For logging into Docker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we will be executing the rest of the push commands as given by ECR.&lt;br&gt;
Now our image is pushed to our ECR repo, as shown below.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Creating a Lambda Function through an ECR Image&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go to AWS → Lambda → click on "Create Function" button&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RED LINE: Select container image&lt;/li&gt;
&lt;li&gt;GREEN LINE: Give a name to the function (Remember that the name of the lambda should match the name of the REPO)&lt;/li&gt;
&lt;li&gt;BLUE LINE: Paste the Image URI from the ECR Repo pushed image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then click on create function.&lt;/p&gt;

&lt;p&gt;Go to the Lambda Function created and click on test to check if it's working fine.&lt;/p&gt;

&lt;p&gt;If it comes back clean, that's your confirmation that the whole chain worked - Dockerfile, application logic, ECR push, Lambda config, all of it. First successful test on a container you built yourself hits differently than a regular deploy.&lt;/p&gt;

&lt;p&gt;If everything works fine, lets go and create trigger for this lambda from API gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: Creating a Trigger For Lambda by AWS API Gateway&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go to API Gateway → Create API → REST API. Give a name to the API collection and click "Create API."&lt;/p&gt;

&lt;p&gt;Now, just create a resource with a path as handled in the application (see index.js file).&lt;/p&gt;

&lt;p&gt;Like in the image below, you can see I have created 2 resources, "products" and "/product". After creating a resource create method for the resources, like for "/products", I have created a GET method and for the "/product", 4 methods are created: GET, POST, PATCH, and DELETE.&lt;/p&gt;

&lt;p&gt;NOTE: Turn on the "Lambda Proxy Integration" to avoid mapping of the event object in your code.&lt;/p&gt;

&lt;p&gt;Seriously - don't overlook this toggle. Leave it off, and the full event object never reaches your handler correctly. Your routing logic breaks, nothing goes where it should, and the error messages won't point you back to this setting. One checkbox saves a genuinely confusing debugging session.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 5: Deploy the APIs and test them&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After creating the APIs, deploy the APIs and take note of the invoking URLs. As shown in the image below.&lt;/p&gt;

&lt;p&gt;Note the invoking URL.&lt;/p&gt;

&lt;p&gt;Below are the APIs tested via POSTMAN.&lt;/p&gt;

&lt;p&gt;Work through every route methodically. Health check first, then fetch a product, create one, update a field, and delete a record. Watch each one return the right response from DynamoDB - routed through API Gateway, processed by your containerized Lambda, handed back clean.&lt;/p&gt;

&lt;p&gt;SUMMARY: The above steps can be imagined as follows:&lt;/p&gt;

&lt;p&gt;Client → API Gateway → Lambda (Docker Container) → DynamoDB + API Gateway integration&lt;/p&gt;

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

&lt;p&gt;In conclusion, Dockerized Lambda functions present significant advantages for custom financial software development, iOS mobile app development companies, and software development for healthcare. By encapsulating Lambda function code and its dependencies within Docker containers, developers in healthcare custom software development and cross-platform mobile app development services gain greater control, flexibility, and efficiency throughout the development lifecycle.&lt;/p&gt;

&lt;p&gt;For businesses seeking offshore software development, Dockerizing Lambda functions provides a reliable approach. It facilitates the hiring of offshore development teams and the engagement of dedicated offshore developers for software development services. Moreover, it streamlines the process of hiring a software development team and ensures efficient software outsourcing — everyone runs the same container, so environment mismatches stop eating into delivery time.&lt;/p&gt;

&lt;p&gt;In essence, Dockerizing Lambda functions empowers software development companies, software development agencies, and application development companies to deliver robust solutions across diverse industries. Whether it’s web development services or software application development, Dockerization enhances the capabilities of software development firms and contributes to their success in the competitive marketplace.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more :&amp;nbsp;&lt;a href="https://innostax.com/blog/dockerized-lambda-transform-your-development-with-efficiency/" rel="noopener noreferrer"&gt;Dockerized Lambda : Transform Your Development with Efficiency&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>lambda</category>
      <category>devops</category>
    </item>
    <item>
      <title>Streamlining Gladly Task Creation with Apex Code</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Mon, 29 Jun 2026 05:13:00 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/streamlining-gladly-task-creation-with-apex-code-c79</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/streamlining-gladly-task-creation-with-apex-code-c79</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gladly tasks are more than to-do items&lt;/strong&gt; - they're structured, assignable, customer-linked follow-up actions with due dates and comments. Understanding that model is what makes the API integration actually useful rather than just functional.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The wrapper class pattern isn't ceremony&lt;/strong&gt;. It's how you keep your Apex code maintainable when the request body has nested objects and your integration needs to evolve over time without breaking everything that calls it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error handling in API integrations&lt;/strong&gt;is the part everyone writes last and regrets skipping first. Build it in from the start - your future self will appreciate it during the first production incident.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you've worked with customer service platforms long enough, you know the problem this integration solves.&lt;/p&gt;

&lt;p&gt;An appointment gets rescheduled in Salesforce. Somewhere, a Gladly agent needs to know about it, follow up with the customer, and close the loop. Without automation, that's a manual step - someone has to remember to create the task, fill in the right details, assign it correctly. Sometimes they do. Sometimes they don't. Sometimes they do it three days later when the customer has already called back twice.&lt;/p&gt;

&lt;p&gt;Apex plus Gladly's task API closes that gap. The follow-up task gets created automatically, assigned correctly, with the right due date and customer context - without anyone having to remember to do it.&lt;/p&gt;

&lt;p&gt;That's what this guide walks through. Not a theoretical overview of what's possible, but the actual code pattern that makes it work.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is a Gladly Task?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before writing any code, it's worth understanding what a Gladly task actually is - because it's not just a generic to-do item.&lt;/p&gt;

&lt;p&gt;A task in Gladly is customer-specific. It lives on a customer's timeline alongside their conversations, emails, and other interactions. It has a body describing what needs to happen, a due date, an assignee (an inbox, a specific agent, or both), and it supports comments. When you create a task through the API, Gladly either attaches it to an existing customer profile or creates a new one if the customer doesn't exist yet.&lt;/p&gt;

&lt;p&gt;That last part matters for the integration. You're not just creating abstract tasks - you're creating follow-up work that lives in the context of a real customer relationship. The API reflects that, which is why the request body requires customer identification alongside the task details.&lt;/p&gt;

&lt;p&gt;Understanding this model upfront saves a lot of confusion when you're looking at the request schema and wondering why customer identification is required when "you just want to create a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Create a Gladly Task?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Gladly exposes a POST endpoint for task creation. The request hits the tasks API, carries a JSON body with everything Gladly needs to create and assign the task, and returns a response you can use for error handling and confirmation.&lt;br&gt;
Here's how to build this in Apex, step by step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;REQUEST BODY SCHEMA: application/json&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pOVVdzweSumI4bFxjlT8LA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"assignee"&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;"inboxId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NFpDZtfqhk2pI6fjaVDlFf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agentId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zGaHXjD4SR-moMR9LbULDa"&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;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Create task to reschedule appointment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dueAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-03-15T06:13:00.125Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer"&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;"emailAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"michelle.smith@example.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mobilePhone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+16505551987"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id
String &amp;amp;lt;= 50 characters
Specifies the id of the task
assignee 
    required
object (Assignee)
Inbox and agent assignee for a task
body
   required
string &amp;amp;lt;= 10000 characters
Text to describe what task to complete. Constrained HTML Rich Content is supported.
dueAt
   required
string &amp;amp;lt;RFC3339&amp;amp;gt;
Time when the task will be due. This must be set to a time in the future.
Customer
   required
object (Customer Specification)
Specifies the customer a task belongs to. You must provide exactly one of the values.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;*&lt;em&gt;Create Apex Wrapper Classes for Task Management
public class TaskWrapper *&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apex"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskWrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;AssigneeWrapper&lt;/span&gt; &lt;span class="n"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;dueAt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;CustomerWrapper&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TaskWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AssigneeWrapper&lt;/span&gt; &lt;span class="n"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;dueAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CustomerWrapper&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;assignee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;dueAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dueAt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customer&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerWrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;emailAddress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CustomerWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;emailAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AssigneeWrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;agentId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AssigneeWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;inboxId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AssigneeWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;agentId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;inboxId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;agentId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agentId&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Method to Construct the Request Body with Required Parameters&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apex"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createTaskToRescheduleAppointment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;previousDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;newDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;taskBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
             &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;lt;strong&amp;amp;gt;Appointment Rescheduled:&amp;amp;lt;/strong&amp;amp;gt; &amp;amp;lt;br&amp;amp;gt;Your appointment has been rescheduled to '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
             &lt;span class="n"&gt;newDate&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
             &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt; from &amp;amp;lt;strong&amp;amp;gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
             &lt;span class="n"&gt;previousDate&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;
             &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;lt;/strong&amp;amp;gt;.&amp;amp;lt;br/&amp;amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

         &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="c1"&gt;// Implement logic to get the inbox ID according to your needs.&lt;/span&gt;
             &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;inboxId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getInboxId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;AssigneeWrapper&lt;/span&gt; &lt;span class="n"&gt;assignee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AssigneeWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inboxId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;CustomerWrapper&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CustomerWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Either Create a method to get the dueAt date for the new task or use any value directly for the due date according to your requirement.&lt;/span&gt;
             &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;dueAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRescheduleDueDate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;TaskWrapper&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TaskWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;taskBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dueAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nf"&gt;createTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&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;span class="c1"&gt;// handle the catch block according to your requirement.&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create the createTask Method to Handle the POST Request&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apex"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TaskWrapper&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&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="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nf"&gt;createTaskOnGladly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt; &lt;span class="nf"&gt;createTaskOnGladly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TaskWrapper&lt;/span&gt; &lt;span class="n"&gt;gladlyTaskWrapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gladlyTaskWrapper&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;GLADLY_ENDPOINT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;lt;organization&amp;amp;gt;.gladly.com/api/v1/tasks'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLADLY_ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;POST'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;Content-Type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;application/json;charset=UTF-8'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Http&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="c1"&gt;// Get the status code of the API request and handle additional features&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&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="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;What this integration actually buys you is reliability. Tasks get created when they should, with the right information, assigned to the right place - not when someone remembers to create them manually.&lt;br&gt;
The wrapper class pattern keeps the code maintainable as requirements evolve. The method separation keeps concerns clean - one method builds the task, one sends it, and the calling code doesn't need to know about either. When Gladly changes something about its API, or your business rules around inbox assignment change, you know exactly where to go.&lt;br&gt;
The real work after getting this running is the error handling and observability you build around it. What happens when the callout fails? What happens when Gladly returns an unexpected status? How will you know if tasks stop being created? Those questions are worth answering before you put this in production, not after.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014, and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;strong&gt;&lt;a href="https://innostax.com/blog/gladly-task-creation-with-apex-code/" rel="noopener noreferrer"&gt;Streamlining Gladly Task Creation with Apex Code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Maximizing E-Commerce Success with Shopify and Nosto</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Fri, 26 Jun 2026 05:15:20 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/maximizing-e-commerce-success-with-shopify-and-nosto-2m4i</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/maximizing-e-commerce-success-with-shopify-and-nosto-2m4i</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Showing every visitor the same store experience in 2024 is the e-commerce equivalent of handing everyone the same menu regardless of whether they’re a first-time visitor or a customer who’s bought from you twelve times. Nosto fixes this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The technical setup is the easy part. The strategy — how you segment, what content rules you create, where you place recommendations — that’s where the actual results come from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The retention impact compounds quietly. Customers who feel like your store understands them come back more often, spend more when they do, and cost less to retain than new customers cost to acquire. That math matters more than the conversion rate headline.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I want to start with something that sounds obvious but apparently isn't, because most Shopify stores I've seen aren't doing it.&lt;/p&gt;

&lt;p&gt;Your customers are not the same person.&lt;/p&gt;

&lt;p&gt;The visitor who found your store through a Pinterest ad for handmade candles and the returning customer who's bought six times and spent $800 with you should not be seeing identical experiences. But in most stores, they are. Same homepage. Same featured collection. Same promotional banner. The store has no idea who it's talking to and shows everyone the same thing.&lt;/p&gt;

&lt;p&gt;That's not a technology problem. The technology to fix it has existed for years. It's a prioritization problem - personalization gets deprioritized because it feels complicated, and most store owners don't see the cost of not doing it until they start doing it and see the difference.&lt;/p&gt;

&lt;p&gt;Nosto connected to Shopify is how you fix it. And it's more accessible than most people assume.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Personalization Matters in E-Commerce&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's the number that matters most: personalized shopping experiences can increase sales by up to 15%. That gets cited a lot. What gets cited less is the retention story.&lt;/p&gt;

&lt;p&gt;Acquiring a new customer costs five to seven times more than retaining an existing one - and personalization is one of the most reliable retention drivers available. When a customer feels like your store recognizes them, remembers what they like, and consistently surfaces things relevant to them, they develop a different relationship with it. They come back. They spend more when they do. They're more forgiving when something goes wrong.&lt;/p&gt;

&lt;p&gt;Nosto is an AI-driven personalization platform that connects directly to Shopify. It uses behavioral data - what customers browse, what they buy, how they navigate - to deliver personalized product recommendations, dynamic content, and targeted campaigns across the entire customer journey. It's not just a "you might also like" widget. It's a system that learns your customers and adapts to them over time.&lt;/p&gt;

&lt;p&gt;The Shopify App Store integration makes it accessible without heavy development work. But accessible doesn't mean automatic - how well it performs depends almost entirely on how thoughtfully you configure it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Nosto Integrates with Shopify&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Install the Nosto App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the Shopify App Store, search for Nosto, and click "Add app." The installation process walks you through linking your Shopify store to Nosto - this connection is the foundation of everything. Without it, Nosto can't access your product catalog, customer data, or behavioral signals, which means it can't personalize anything.&lt;/p&gt;

&lt;p&gt;The setup takes about ten minutes if your store data is reasonably clean. If you have product data issues - missing descriptions, inconsistent tags, messy categorization - it's worth cleaning those up first. Nosto's recommendations are only as good as the product data it's working with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Nosto Account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're new to Nosto, the app guides you through account creation as part of setup. Once the account exists, you link it to your Shopify store. This activates the data sync - product catalogs, customer behavior, and order history all start flowing into Nosto.&lt;/p&gt;

&lt;p&gt;One thing to be realistic about: day one performance won't tell you much. Nosto needs behavioral data to build accurate audience profiles, and that takes time with real traffic. Give it three to four weeks before making any significant configuration changes based on performance data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure the Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the connection is live and data is syncing, you start configuring where and how recommendations appear. The Nosto dashboard lets you control placement - homepage, product pages, cart pages, checkout - and the algorithm behind each placement.&lt;/p&gt;

&lt;p&gt;Not all placements are equal. Product page recommendations ("customers also bought") and cart page recommendations ("frequently bought together") have the most direct impact on average order value because they appear when purchase intent is already high. Homepage personalization has the biggest impact on engagement and bounce rate for returning visitors.&lt;/p&gt;

&lt;p&gt;I recommend starting with product and cart pages. Get those working well before expanding into homepage personalization and dynamic content. Trying to configure everything at once usually means configuring everything mediocrely.&lt;/p&gt;

&lt;p&gt;Keep recommendations in sync with your actual inventory. A recommendation for something out of stock for two weeks is worse than no recommendation at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Nosto Widgets to Your Store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Widgets are how personalized recommendations actually appear on your pages. In your Shopify admin, go to Online Store → Themes → Customize, and you'll find Nosto's widgets available in the theme editor.&lt;br&gt;
The drag-and-drop interface handles basic placement without developer involvement - that's genuinely useful for most standard implementations. Where you need development support is when widget styling needs to match a custom theme precisely, when you want non-standard layouts, or when you're trying to do something the standard widgets don't accommodate cleanly. Innostax's e-commerce development team handles these kinds of customizations regularly - it's usually a few hours of work rather than a full project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable Dynamic Content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where Nosto goes from "recommendation engine" to "personalization platform," and the distinction is worth understanding.&lt;/p&gt;

&lt;p&gt;Dynamic content means the actual content of your store - banners, hero images, promotional text, featured collections - changes based on who's visiting. A first-time visitor from a paid social campaign sees something different from a returning customer who's bought twice. Someone who's been browsing outerwear for the last three sessions sees different homepage content than someone who's been looking at accessories.&lt;/p&gt;

&lt;p&gt;You set this up through content rules in the Nosto dashboard. Define your segments - first-time visitors, returning browsers, repeat buyers, high-value customers, lapsed customers - and create content variations for each. It's more work than setting up product recommendations, but it's where the engagement numbers really move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrate with Marketing Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nosto connects with Klaviyo, Mailchimp, and other email platforms. This is the piece that extends personalization beyond your storefront into your email program, and it's where the retention story really comes together.&lt;/p&gt;

&lt;p&gt;Automated flows triggered by customer behavior - abandoned cart emails with personalized product recommendations, post-purchase sequences suggesting complementary items, re-engagement campaigns for customers who haven't bought in 90 days - all of these run better when powered by Nosto's behavioral data rather than generic list segments.&lt;/p&gt;

&lt;p&gt;The abandoned cart flow is worth setting up first. Cart abandonment rates in e-commerce typically sit above 70%, and personalized recovery emails with relevant product recommendations consistently outperform generic "you left something behind" messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test and Monitor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Nosto's A/B testing. Seriously, use it - don't just set your initial configuration and assume it's optimal. Test different recommendation algorithms. Test widget placements. Test content variations for different segments. The data almost always surfaces something non-obvious about what your specific audience actually responds to.&lt;/p&gt;

&lt;p&gt;The analytics dashboard tracks conversion rates, average order value, engagement, and Nosto-attributed revenue. Check it regularly, not just for reporting purposes but to inform active decisions about configuration changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Launch Your Personalization Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once email integration is set up and your content rules are live, start your automated email sequences.&lt;/p&gt;

&lt;p&gt;Create flows for different lifecycle stages rather than treating your list as a single audience. New subscribers get a welcome sequence with personalized product suggestions based on their browsing behavior. Active customers get recommendations calibrated to their purchase history. Lapsed customers - anyone who hasn't bought in 60 to 90 days - get re-engagement campaigns with offers calibrated to their historical value.&lt;/p&gt;

&lt;p&gt;The goal in every touchpoint is to make the communication feel relevant to the specific person receiving it, not like a broadcast to your entire list. That's what changes the relationship over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Benefits of Nosto and Shopify Integration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Customer Insight Improved&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond the conversion and revenue impact, Nosto generates genuinely useful customer intelligence. Browsing patterns, product affinity by segment, purchase triggers, navigation behavior - this data feeds back into product decisions, merchandising strategy, and marketing. It tells you things about your customers that your Shopify analytics alone won't surface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Higher Conversion Rates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the headline benefit, and it's real. Relevant recommendations convert at meaningfully higher rates than generic catalog browsing - customers who see products matched to their demonstrated preferences add to cart more often than customers browsing cold. The conversion lift is usually the first thing that shows up in analytics after launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Higher Average Order Value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well-placed recommendations on product and cart pages consistently drive average order value up by surfacing complementary and higher-margin items at the moment when purchase intent is already established. Customers who are already buying are the easiest to sell more to - Nosto makes that conversation feel like helpful curation rather than upselling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Customer Retention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the benefit that takes the longest to show up in data and matters most long-term.&lt;/p&gt;

&lt;p&gt;Customers who have consistently personalized, relevant experiences in your store develop a fundamentally different relationship with it than customers who feel like they're browsing a catalog that doesn't know them. They return more frequently, they spend more when they return, and they're more likely to tell people about the store. For e-commerce businesses where acquisition costs are high and margins are thin, this compounds in ways that make a real difference to the business over a one to two-year horizon.&lt;/p&gt;

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

&lt;p&gt;Look, Nosto isn't a substitute for a good product. If your catalog is weak or your pricing isn't competitive, personalization will show customers the wrong things faster and more efficiently - which isn't helpful.&lt;/p&gt;

&lt;p&gt;But if the fundamentals are solid and you're looking for meaningful levers to improve conversion and retention, this integration is worth taking seriously. The setup is more accessible than most store owners expect. The performance compounds over time as Nosto accumulates behavioral data. And the retention impact - the part that doesn't show up in week one analytics but matters enormously over a longer time horizon - is where the real business value lives.&lt;/p&gt;

&lt;p&gt;Don't treat implementation as a checkbox. Generic configuration gets generic results. The stores that get 20–25% improvements are the ones that put real thought into segmentation, content rules, and recommendation placement - not the ones that installed the app and left everything on default.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Innostax specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://innostax.com/blog/maximizing-e-commerce-success-with-shopify-and-nosto/" rel="noopener noreferrer"&gt;Maximizing E-Commerce Success with Shopify and Nosto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Simplify Complex Data Handling with AG Grid in React</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Thu, 25 Jun 2026 05:04:43 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/simplify-complex-data-handling-with-ag-grid-in-react-2je5</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/simplify-complex-data-handling-with-ag-grid-in-react-2je5</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stop building custom tables. AG Grid ships with everything&lt;/strong&gt; - virtualization, filtering, grouping, export, and inline editing - and it's free. The community edition alone covers most of what teams spend months building from scratch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom cell editors follow one pattern:&lt;/strong&gt; build a React component, expose getValue() via useImperativeHandle, pass it as cellEditor. That's the whole thing. The rest is just React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom sorting&lt;/strong&gt; is a comparator function with two values in and a number out. Sounds trivial. In practice, it solves sorting problems that alphabetical and numeric ordering can never handle correctly for domain-specific data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I want to say something upfront that might sound obvious but apparently isn't, because I keep seeing teams do the opposite.&lt;/p&gt;

&lt;p&gt;Don't build a data table from scratch in 2024. Just don't.&lt;/p&gt;

&lt;p&gt;I've been on teams that did this. Everyone agrees it'll be "simple." A few weeks later someone's maintaining three hundred lines of sorting logic, a custom virtualization implementation that works okay on Chrome but behaves weirdly on Safari, and a filter system that the original developer understands but nobody else does. Then that developer leaves.&lt;/p&gt;

&lt;p&gt;AG Grid exists. It's good. The community edition is free. Use it.&lt;/p&gt;

&lt;p&gt;Okay, rant over. Let me actually show you how it works - and specifically how to extend it when the defaults aren't enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Is AG GRID&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AG Grid is a JavaScript data grid built for applications where data isn't just displayed - it's worked with. Filtered, sorted, grouped, edited, exported. There's a real difference between a library built for read-only display and one built for interactive data work, and AG Grid is firmly in the second category.&lt;/p&gt;

&lt;p&gt;The performance is legit. Row virtualization runs by default, meaning it only renders what's visible in the viewport regardless of how many rows live in the dataset. Scroll through a hundred thousand rows and it stays smooth because it's not actually painting a hundred thousand DOM nodes. Most table components handle this badly or not at all.&lt;/p&gt;

&lt;p&gt;Our React team at Innostax has shipped AG Grid into fintech dashboards with real-time data updates, healthcare record systems where clinical teams are filtering through thousands of patient entries, SaaS admin panels where operations people live in the grid all day. It holds up in ways that simpler libraries simply don't when the pressure increases.&lt;/p&gt;

&lt;p&gt;What makes it worth learning properly isn't just the features - it's that the extension model is clean. Custom cell renderers, custom editors, custom sort comparators, custom filters - they all follow the same pattern. Build a thing, plug it in, AG Grid handles the lifecycle. Once that clicks, the whole library opens up.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Features Of AG GRID&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rather than walking through every feature&lt;/strong&gt; - the AG Grid docs do that better than any blog post - here's what actually matters day-to-day:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Column definitions are everything&lt;/strong&gt;. How a column sorts, filters, renders, whether it's editable, how it groups - all of it lives in the column definition object. The entire API kind of radiates outward from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sorting and filtering are built in and actually good&lt;/strong&gt;. Multi-column sort works. Complex filter combinations work. You configure them, you don't build them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grouping and aggregation are production-ready&lt;/strong&gt;. Expandable row groups, aggregate functions on grouped data, subtotals - configuration, not custom code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cell renderers are just React components&lt;/strong&gt;. Status badges, sparklines, progress bars, avatar + name combos - build a component, pass it as cellRenderer, Clean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Virtualization is on by default&lt;/strong&gt;. You don't turn it on. You'd have to turn it off, which you wouldn't want to do.&lt;/p&gt;

&lt;p&gt;The community edition is free and genuinely capable. Enterprise adds Excel export, server-side row model, master-detail - useful things, but the free tier gets you surprisingly far before you need any of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Uses Of AG GRID&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Short version&lt;/strong&gt;: anywhere your users interact with tabular data rather than just glance at it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise and internal tools&lt;/strong&gt; - CRMs, ERPs, operations dashboards. People spending their workday in a grid need one that actually works under sustained use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fintech&lt;/strong&gt; - Portfolio views, trading data, real-time price feeds. AG Grid handles fast-updating data without re-rendering the world on every tick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthcare&lt;/strong&gt; - Clinical data, patient records, scheduling. Filtering through thousands of records quickly isn't a nice-to-have when someone's trying to find a patient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SaaS products&lt;/strong&gt; - Almost every SaaS has a data table somewhere that users care about. AG Grid is consistently the right answer for that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics and reporting&lt;/strong&gt; - The tabular half of a data product. Pair it with a charting library, and you've got a solid analytics UI without building either component yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-commerce and logistics&lt;/strong&gt; - Inventory, orders, catalog management. High-volume datasets that operations teams work with constantly, not casually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Genuinely &lt;/strong&gt;- if there's a table in your app and users actually care about it, AG Grid is probably the right tool. The question is how much of it you need, not whether it fits.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding Custom Cell Editor&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The built-in editors cover maybe 70% of real use cases. Text input, number input, select dropdown. They're fine.&lt;/p&gt;

&lt;p&gt;The other 30% is where it gets interesting. A date range picker. A searchable multi-select. A custom input with validation logic that's specific to your domain. An editor that matches your design system instead of looking like it came from a different application.&lt;/p&gt;

&lt;p&gt;Custom editors handle all of this. And the pattern, once you've seen it once, is genuinely straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we begin, ensure that you have the following prerequisites:&lt;/p&gt;

&lt;p&gt;A basic understanding of JavaScript and React (though you can use ag-Grid with other frameworks or plain JavaScript).&lt;br&gt;
An ag-Grid project set up. If you haven't already, you can install it via npm or yarn:&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Why go custom?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Three situations where the defaults stop working:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unusual data types&lt;/strong&gt; - Coordinates, color values, complex objects. The text input accepts anything but formats and validates nothing useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User experience&lt;/strong&gt; - A purpose-built editor that fits your design system is better than a generic input. Users feel the difference even when they can't name it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain-specific validation&lt;/strong&gt; - Not "is this a number" but "is this a valid product code for our catalog." That logic belongs in the editor, not scattered through form handlers elsewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set Up Your AG Grid Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create or locate GridComponent.js - wherever AG Grid lives in your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Define the Custom Cell Editor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;useImperativeHandle is the integration point. It exposes getValue() to AG Grid - that's how the grid retrieves the edited value when the user confirms a change. Everything else is plain React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Integrate the Custom Cell Editor with AG Grid&lt;/strong&gt;&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="c1"&gt;// GridComponent.js import React from 'react';&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AgGridReact&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-community/styles/ag-grid.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-community/styles/ag-theme-alpine.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TextEditor&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./TextEditor&lt;/span&gt;&lt;span class="dl"&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;GridComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&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;columnDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Define your column definitions here&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Custom Edit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customEditField&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;cellEditor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textEditor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gridOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;frameworkComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;textEditor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TextEditor&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ag-theme-alpine&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;AgGridReact&lt;/span&gt;
&lt;span class="nx"&gt;columnDefs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;columnDefs&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;rowData&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;yourData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;gridOptions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;gridOptions&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;amp;gt&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;amp;gt&lt;/span&gt;&lt;span class="err"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;GridComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;cellEditor&lt;/strong&gt;: TextEditor is literally the whole integration. AG Grid handles when the editor opens, when it closes, when it calls getValue(). You handle what the editor looks like and what it validates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handle the Edited Value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use onCellValueChanged to react to confirmed edits - sync to an API, update local state, trigger downstream logic. AG Grid owns the editing lifecycle. You own what happens with the result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customize and Style&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's a React component. Style it however your project styles things. The goal is making it feel native to your application. Users shouldn't feel like they've entered "grid editing mode" - they should just be editing data.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Implementing Custom Sorting&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Default sorting in AG Grid is alphabetical or numeric. For a lot of columns that's exactly right and you never think about it.&lt;br&gt;
Then you hit a status column. Values are "Draft," "In Review," "Published," "Archived." Alphabetically, "Archived" sorts first. That's wrong in every way that matters to the people using your product.&lt;br&gt;
Or part numbers: "A-9" and "A-10." Alphabetically "A-10" comes before "A-9." Again - wrong. Not wrong by some technical definition, wrong in terms of what users expect and need.&lt;br&gt;
Custom comparators fix this. The API is minimal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Define a Custom Sorting Algorithm&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customSort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&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;lengthA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&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;lengthB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&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;lengthA&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;lengthB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;nbsp&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;lengthA&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;lengthB&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="mi"&gt;1&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;Sorting by string length here - contrived example, but the shape of the function is what matters. Two values in, a number out. Negative means a comes first, positive means b, zero means equal. Same contract as Array.sort. Replace the comparison logic with whatever your domain actually requires.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Integrate Custom Sorting into AG Grid&lt;/strong&gt;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AgGridReact&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-community/dist/styles/ag-grid.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ag-grid-community/dist/styles/ag-theme-alpine.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;customSort&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./CustomSort&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the custom sort function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;YourComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&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;columnDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// Add the custom sort function to the column definition&lt;/span&gt;
      &lt;span class="na"&gt;comparator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customSort&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="na"&gt;headerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// … other column definitions&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;rowData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane Smith&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// … other row data&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ag-theme-alpine&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;300px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;AgGridReact&lt;/span&gt;
        &lt;span class="nx"&gt;columnDefs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;columnDefs&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;rowData&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rowData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&amp;amp;gt&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;amp;gt&lt;/span&gt;&lt;span class="err"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;YourComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ve added the comparator property to the column definition and assigned it the custom sort function (customSort). The comparator property allows us to specify a custom comparison function for sorting.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;comparator in the column definition. That's the API. AG Grid calls it during sort and uses the result to order rows. Your custom logic runs exactly where it should - close to the data, in the column that owns it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Testing the Custom Sorting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the app, click the "Name" header, and watch rows sort by string length. Then replace the logic with your actual business rules. Status ordering, natural sort for alphanumeric strings, date range comparisons, priority tiers - all of it works through the same interface.&lt;/p&gt;

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

&lt;p&gt;The best thing about AG Grid's extension model is that it doesn't ask you to fight the library to get what you want.&lt;/p&gt;

&lt;p&gt;Custom sorting, custom editors, custom renderers - they all slot in cleanly. You build a thing, you plug it in, AG Grid does its job and calls your code at the right moment. There's no wrestling with internal abstractions or working around opinions baked into the library. It just… works the way you'd want it to.&lt;/p&gt;

&lt;p&gt;That matters a lot in practice. Tools that are easy to extend tend to get extended. Teams actually build the specialized features their users need, rather than settling for "close enough." The grid ends up shaped around the product rather than the product being shaped around the grid.&lt;/p&gt;

&lt;p&gt;If your application is data-intensive - and a lot of the most important applications are - AG Grid is genuinely worth learning properly. The ceiling is high, the defaults are solid, and when you need something specific, the path to building it is straightforward. That combination is rarer than it sounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Innostax&lt;/strong&gt; specializes in managed engineering teams and was founded in 2014, and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more&lt;/strong&gt;: &lt;a href="https://innostax.com/blog/complex-data-react/" rel="noopener noreferrer"&gt;Simplify Complex Data Handling with AG Grid in React.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Implementing Cloud Computing in Healthcare Is a Game-Changing Solution?</title>
      <dc:creator>Sahil Khurana</dc:creator>
      <pubDate>Wed, 24 Jun 2026 05:43:38 +0000</pubDate>
      <link>https://dev.to/sahil_khurana_486f374ecf2/why-implementing-cloud-computing-in-healthcare-is-a-game-changing-solution-4g8o</link>
      <guid>https://dev.to/sahil_khurana_486f374ecf2/why-implementing-cloud-computing-in-healthcare-is-a-game-changing-solution-4g8o</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud computing in healthcare isn't just an IT upgrade&lt;/strong&gt; — it's fundamentally changing how patient data gets accessed, shared, and protected. Doctors making decisions at 2am now have everything they need, instantly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security isn't an afterthought with healthcare cloud&lt;/strong&gt; — it's baked in from day one. Encryption, access controls, HIPAA compliance — the good providers handle all of it so healthcare teams don't have to become cybersecurity experts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The real value isn't in the technology itself&lt;/strong&gt; — it's in what it unlocks. Better collaboration between care teams, faster diagnoses, lower operational costs, and room to actually innovate without rebuilding your entire infrastructure first.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let me tell you something that doesn't get said enough in healthcare technology conversations: the gap between how healthcare should work and how it actually works today is often just an infrastructure problem.&lt;br&gt;
Brilliant doctors. Dedicated nurses. World-class researchers. All of them slowed down by outdated systems, siloed data, and IT infrastructure that was never designed for the way modern medicine works. Patients suffer for it — sometimes literally.&lt;br&gt;
Cloud computing isn't a silver bullet. But when it's implemented thoughtfully in a healthcare setting, it closes that gap faster than almost anything else available right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Cloud Computing?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most people have a vague sense of what cloud computing means — something about servers somewhere that aren't in your building. That's technically accurate but misses the point entirely for healthcare.&lt;/p&gt;

&lt;p&gt;In a healthcare context, cloud computing means that patient records, medical imaging, diagnostic tools, communication systems, and research platforms all live in a secure, remotely accessible environment. A cardiologist in Boston can review scans from a patient who was admitted in Phoenix. A rural clinic can run the same electronic health record system as a major urban hospital. A research team can process genomic data that would have required a warehouse full of servers a decade ago.&lt;br&gt;
That's what cloud computing actually means for healthcare — not just "storage in the sky" but a complete rethinking of what's possible when your infrastructure isn't physically stuck in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Advantages of Cloud Computing in Healthcare&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Enhanced Accessibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one sounds obvious until you've seen what it looks like in practice.&lt;/p&gt;

&lt;p&gt;When patient data lives in a cloud-based system, the right people can access it at the right moment — regardless of where they are or what device they're on. A hospitalist getting called at midnight doesn't need to drive in to check a chart. An ER physician doesn't need to wait for a fax from another facility. That access, in real time, genuinely changes outcomes.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Improved Collaboration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Healthcare is a team sport. Always has been. But for decades, the tools available to care teams made real collaboration surprisingly difficult — different systems, different formats, information living in silos that didn't talk to each other.&lt;/p&gt;

&lt;p&gt;Cloud-based healthcare platforms break those silos down. Multiple specialists can review the same patient record simultaneously. Care teams across different facilities can coordinate without playing phone tag. The information flows the way the care actually should.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's something that keeps healthcare IT teams up at night: a regional hospital that handles 300 patients a day doesn't need the same infrastructure as one handling 3,000. But it might need to scale quickly if there's a crisis, a flu season that hits harder than expected, or a merger with a larger system.&lt;/p&gt;

&lt;p&gt;Cloud infrastructure scales with you. Up when you need it, back down when you don't. You pay for what you actually use. That kind of flexibility is genuinely hard to replicate with on-premises hardware.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Data Security&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A properly configured cloud environment for healthcare includes end-to-end encryption, granular access controls, audit trails, and threat monitoring that most hospitals could never afford to build and maintain themselves. The major cloud providers have entire teams — hundreds of people — whose only job is security. Your on-premises server room probably doesn't.&lt;/p&gt;

&lt;p&gt;HIPAA compliance, GDPR, HITECH — serious healthcare cloud providers build compliance into the architecture, not bolt it on afterward.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cost-Effectiveness&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The old model required massive upfront capital investment — servers, storage, networking equipment, facilities to house it all, staff to maintain it. And that investment depreciated whether you needed it or not.&lt;br&gt;
Cloud flips that model completely. You're not buying infrastructure, you're renting capacity. The capital expenditure becomes an operational one. For healthcare organizations already running on thin margins, that shift can free up resources that go directly into patient care.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Integration of Emerging Technologies&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the one that gets me genuinely excited about where healthcare is heading.&lt;/p&gt;

&lt;p&gt;AI-powered diagnostics, telemedicine platforms, remote patient monitoring, predictive analytics for readmission prevention — none of these emerging technologies work well if they're constantly fighting against legacy infrastructure. Cloud gives them the foundation they need to actually deliver on their promise. AI integration in healthcare is only as good as the infrastructure underneath it, and the cloud is increasingly that infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Healthcare Cloud Computing Development Services&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The technology itself is only part of the story. How you implement it — and who helps you do it — matters just as much as which platform you choose.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Software Development&lt;/strong&gt;&lt;br&gt;
Off-the-shelf healthcare software is a good starting point. But every health system has workflows, specialties, patient populations, and operational realities that generic software wasn't designed for.&lt;br&gt;
Custom healthcare software development builds around how your teams actually work — not how a software company imagined they might work. EHR systems that match your clinical workflows, patient portals that reflect your organization's specific services, and care coordination tools built for your patient population. Done right, it makes the technology disappear into the background and lets your people focus on patients.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Migration and Integration&lt;/strong&gt;&lt;br&gt;
Moving to the cloud from legacy systems is genuinely complex — especially in healthcare, where you're dealing with decades of historical data, systems that weren't designed to talk to each other, and zero tolerance for downtime.&lt;br&gt;
Good cloud migration isn't just a technical lift-and-shift. It's a thoughtful process of mapping what you have, designing what you want, migrating carefully, validating everything, and training the people who'll use it. Shortcuts here tend to be expensive in ways that become apparent only after the fact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security and Compliance&lt;/strong&gt;&lt;br&gt;
In healthcare, a data breach isn't just an embarrassment — it's a potential HIPAA violation, a reputational crisis, and a genuine risk to patient safety and trust.&lt;br&gt;
Healthcare cloud security has to be treated as a first-class concern from day one. Encryption at rest and in transit, role-based access controls, regular penetration testing, audit logging, and incident response planning. And compliance isn't a one-time checkbox — regulations evolve, and your security posture has to evolve with them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure Management and Optimization&lt;/strong&gt;&lt;br&gt;
Getting to the cloud is step one. Making sure it runs efficiently, cost-effectively, and reliably over time is the ongoing work that often gets underestimated.&lt;br&gt;
Managed cloud operations for healthcare means continuous monitoring, proactive optimization, workload management, and the kind of performance tuning that keeps systems running smoothly even as demand fluctuates. It's not glamorous work. But it's the difference between a cloud investment that delivers on its promise and one that slowly turns into a different kind of headache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Support and Maintenance&lt;/strong&gt;&lt;br&gt;
Healthcare systems don't get to have maintenance windows that shut down patient care. The support and maintenance model for healthcare cloud has to reflect that reality — proactive monitoring, rapid response when issues arise, and ongoing updates that get tested thoroughly before they touch production environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Look, healthcare is complicated. The patients are complicated. The regulations are complicated. The workflows are complicated. Anyone who tells you that cloud computing is going to simplify all of that is overselling it magically.&lt;br&gt;
What it genuinely does — when implemented with care and expertise — is remove the infrastructure friction that impedes good care. It gives clinicians the information they need when they need it. It lets care teams collaborate the way modern medicine requires. It lets organizations scale up when demand spikes without making impossible capital investments. And it creates the foundation that actually makes innovations like AI diagnostics and remote monitoring viable in a real clinical setting, not just a pilot study.&lt;br&gt;
The healthcare organizations that figure this out early aren't just cutting IT costs. They're building the operational capability that lets them compete, innovate, and actually serve patients better over the next decade.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;About Innostax&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Innostax&lt;/strong&gt; specializes in managed engineering teams and was founded in 2014. It is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more: &lt;a href="https://innostax.com/blog/why-implementing-cloud-computing-in-healthcare-is-a-game-changing-solution/" rel="noopener noreferrer"&gt;Why Implementing Cloud Computing in Healthcare Is a Game-Changing Solution?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
