<?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: Navin Prasad</title>
    <description>The latest articles on DEV Community by Navin Prasad (@navinkprasad).</description>
    <link>https://dev.to/navinkprasad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F881459%2F95959a43-fc61-4444-8cfc-6ed7ee8a8f90.jpeg</url>
      <title>DEV Community: Navin Prasad</title>
      <link>https://dev.to/navinkprasad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/navinkprasad"/>
    <language>en</language>
    <item>
      <title>10 Easy Steps to Effortlessly Build RESTful API CRUD Operations in Ruby on Rails</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Fri, 21 Jun 2024 04:57:01 +0000</pubDate>
      <link>https://dev.to/navinkprasad/10-easy-steps-to-effortlessly-build-restful-api-crud-operations-in-ruby-on-rails-ne9</link>
      <guid>https://dev.to/navinkprasad/10-easy-steps-to-effortlessly-build-restful-api-crud-operations-in-ruby-on-rails-ne9</guid>
      <description>&lt;p&gt;Building a RESTful API with CRUD (Create, Read, Update, Delete) operations using Ruby on Rails (RoR) can seem daunting at first. However, Rails’ conventions and powerful features make it a smooth and efficient process. In this guide, we’ll walk you through the steps of setting up a RESTful API with CRUD operations using Ruby on Rails, from setting up the environment to deploying the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Setting Up the Environment&lt;/li&gt;
&lt;li&gt;Creating a New Rails Application&lt;/li&gt;
&lt;li&gt;Generating a Scaffold&lt;/li&gt;
&lt;li&gt;Configuring Routes&lt;/li&gt;
&lt;li&gt;Understanding the Controller Actions&lt;/li&gt;
&lt;li&gt;Testing the API Endpoints&lt;/li&gt;
&lt;li&gt;Handling Errors and Validations&lt;/li&gt;
&lt;li&gt;Securing the API&lt;/li&gt;
&lt;li&gt;Deploying the Application&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1. Introduction
&lt;/h4&gt;

&lt;p&gt;RESTful APIs follow a set of principles that allow clients to interact with server-side resources via HTTP requests. CRUD operations represent the four basic functions of persistent storage: Create, Read, Update, and Delete. Ruby on Rails, with its elegant syntax and rich library of features, is an excellent framework for building such APIs.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Setting Up the Environment
&lt;/h4&gt;

&lt;p&gt;Before we start, ensure you have the following installed on your machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby (version 2.7.0 or higher)&lt;/li&gt;
&lt;li&gt;Rails (version 6.0 or higher)&lt;/li&gt;
&lt;li&gt;PostgreSQL (or another preferred database)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Creating a New Rails Application
&lt;/h4&gt;

&lt;p&gt;Create a new Rails application by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new blog_api --api -d postgresql
cd blog_api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--api&lt;/code&gt; flag generates a slimmed-down version of Rails specifically for API-only applications. The &lt;code&gt;-d postgresql&lt;/code&gt; flag sets PostgreSQL as the database.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Generating a Scaffold
&lt;/h4&gt;

&lt;p&gt;Rails scaffolding quickly generates a set of CRUD operations for a resource. Let’s create a scaffold for a &lt;code&gt;Post&lt;/code&gt; resource with &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate scaffold Post title:string body:text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model (&lt;code&gt;post.rb&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Database migration (&lt;code&gt;db/migrate&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Controller (&lt;code&gt;posts_controller.rb&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Routes&lt;/li&gt;
&lt;li&gt;JSON views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the migration to create the posts table in your database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails db:create
rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Configuring Routes
&lt;/h4&gt;

&lt;p&gt;Rails automatically adds routes for the &lt;code&gt;Post&lt;/code&gt; resource. Open &lt;code&gt;config/routes.rb&lt;/code&gt; to confirm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rails.application.routes.draw do
  resources :posts
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets up RESTful routes for the &lt;code&gt;Post&lt;/code&gt; resource.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Understanding the Controller Actions
&lt;/h4&gt;

&lt;p&gt;The generated &lt;code&gt;PostsController&lt;/code&gt; includes actions for CRUD operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;index&lt;/code&gt;: Retrieves all posts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;show&lt;/code&gt;: Retrieves a single post by ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create&lt;/code&gt;: Creates a new post&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update&lt;/code&gt;: Updates an existing post by ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;destroy&lt;/code&gt;: Deletes a post by ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each action corresponds to a specific HTTP method and endpoint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /posts/:id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PUT/PATCH /posts/:id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DELETE /posts/:id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  7. Testing the API Endpoints
&lt;/h4&gt;

&lt;p&gt;Start the Rails server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use tools like Postman or &lt;code&gt;curl&lt;/code&gt; to test the API endpoints. Here’s how you can test each action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a post:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST http://localhost:3000/posts -d "post[title]=First Post&amp;amp;post[body]=This is the body of the first post."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Retrieve all posts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:3000/posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Retrieve a single post:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:3000/posts/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update a post:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PATCH http://localhost:3000/posts/1 -d "post[title]=Updated Title"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete a post:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X DELETE http://localhost:3000/posts/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. Handling Errors and Validations
&lt;/h4&gt;

&lt;p&gt;Add validations to the &lt;code&gt;Post&lt;/code&gt; model to ensure data integrity. Open &lt;code&gt;app/models/post.rb&lt;/code&gt; and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Post &amp;lt; ApplicationRecord
  validates :title, presence: true, length: { minimum: 5 }
  validates :body, presence: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; actions in &lt;code&gt;PostsController&lt;/code&gt; to handle invalid data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create
  @post = Post.new(post_params)

  if @post.save
    render json: @post, status: :created, location: @post
  else
    render json: @post.errors, status: :unprocessable_entity
  end
end

def update
  if @post.update(post_params)
    render json: @post
  else
    render json: @post.errors, status: :unprocessable_entity
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  9. Securing the API
&lt;/h4&gt;

&lt;p&gt;To secure the API, you can implement authentication. One simple way is to use &lt;code&gt;devise&lt;/code&gt; for user authentication and &lt;code&gt;devise-jwt&lt;/code&gt; for token-based authentication.&lt;/p&gt;

&lt;p&gt;Install the necessary gems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'devise'
gem 'devise-jwt'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up &lt;code&gt;devise&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate devise:install
rails generate devise User
rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure &lt;code&gt;devise-jwt&lt;/code&gt; in the &lt;code&gt;User&lt;/code&gt; model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ApplicationRecord
  devise :database_authenticatable, :registerable,
         :jwt_authenticatable, jwt_revocation_strategy: JwtDenylist
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the JWT denylist model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate model JwtDenylist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  10. Deploying the Application
&lt;/h4&gt;

&lt;p&gt;To deploy your application, you can use platforms like Heroku. First, ensure your app is ready for production by adding the necessary gems and configurations. Then, deploy to Heroku with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku create
git push heroku master
heroku run rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  11. Conclusion
&lt;/h4&gt;

&lt;p&gt;You’ve now built a RESTful CRUD API with Ruby on Rails. This guide covered setting up a Rails API, generating a scaffold, configuring routes, handling errors and validations, securing the API, and deploying it. With Rails’ powerful tools and conventions, building and maintaining robust APIs becomes an effortless task.&lt;/p&gt;

&lt;p&gt;Feel free to extend this application by adding more features, improving security, or integrating it with a frontend framework like React or Vue.js. Happy coding!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/restful-api-crud-ruby-on-rails/" rel="noopener noreferrer"&gt;10 Easy Steps to Effortlessly Build RESTful API CRUD Operations in Ruby on Rails&lt;/a&gt; appeared first on &lt;a href="https://codelila.com" rel="noopener noreferrer"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>railsapi</category>
    </item>
    <item>
      <title>Mastering Data Fetching with React’s useSWR Hook</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Sun, 31 Dec 2023 06:00:07 +0000</pubDate>
      <link>https://dev.to/navinkprasad/mastering-data-fetching-with-reacts-useswr-hook-45hb</link>
      <guid>https://dev.to/navinkprasad/mastering-data-fetching-with-reacts-useswr-hook-45hb</guid>
      <description>&lt;p&gt;In the realm of React development, efficient data fetching is a cornerstone for delivering seamless user experiences. As applications grow in complexity, the need for a robust data fetching solution becomes more apparent. Enter &lt;code&gt;useSWR&lt;/code&gt;, a React hook that simplifies and optimizes data fetching, ensuring your application remains responsive and performant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Data fetching in React traditionally involves managing the state of asynchronous requests, handling loading states, errors, and updating the UI accordingly. The &lt;code&gt;useSWR&lt;/code&gt; hook, part of the SWR (stale-while-revalidate) library, streamlines this process, providing a powerful toolset for handling data fetching in React applications.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore the key features of the &lt;code&gt;useSWR&lt;/code&gt; hook, dive into its usage with real-world examples, and discuss how it aligns with React’s vision, including compatibility with React Suspense. Whether you’re a seasoned React developer or just starting your journey, understanding and mastering &lt;code&gt;useSWR&lt;/code&gt; can significantly enhance your ability to manage and fetch data efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;useSWR&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;At its core, &lt;code&gt;useSWR&lt;/code&gt; is a React hook designed to handle data fetching with a focus on simplicity, performance, and reactivity. The hook is part of the SWR library, which adopts a “stale-while-revalidate” strategy. Let’s break down the key aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Caching:&lt;/strong&gt; One of the standout features of &lt;code&gt;useSWR&lt;/code&gt; is its automatic caching mechanism. When you fetch data using the hook, it caches the result, allowing subsequent requests for the same data to be served from the cache rather than making redundant network requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale-While-Revalidate Strategy:&lt;/strong&gt; The SWR library employs a “stale-while-revalidate” strategy. When data is requested, it returns the cached data immediately (if available), and concurrently revalidates the data in the background. This ensures that the user sees immediate results while the app remains up-to-date with the latest data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; &lt;code&gt;useSWR&lt;/code&gt; simplifies error handling by providing a built-in mechanism to retry failed requests. This allows developers to implement custom error handling strategies and gracefully recover from network or server issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use the &lt;code&gt;useSWR&lt;/code&gt; hook, you’ll need to follow a few steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install SWR
&lt;/h3&gt;

&lt;p&gt;First, you need to install the &lt;code&gt;swr&lt;/code&gt; library in your project. You can do this using npm or yarn:&lt;/p&gt;

&lt;p&gt;Using npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install swr

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

&lt;/div&gt;



&lt;p&gt;Using yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add swr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Import the &lt;code&gt;useSWR&lt;/code&gt; Hook
&lt;/h3&gt;

&lt;p&gt;In your React component file, import the &lt;code&gt;useSWR&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import useSWR from 'swr';

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Define a Fetcher Function
&lt;/h3&gt;

&lt;p&gt;Create a function that fetches your data. This function will be passed to &lt;code&gt;useSWR&lt;/code&gt; as the second argument. It can be a simple function that fetches data from an API endpoint using &lt;code&gt;fetch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetchData = (url) =&amp;gt; fetch(url).then(response =&amp;gt; response.json());

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Use the &lt;code&gt;useSWR&lt;/code&gt; Hook
&lt;/h3&gt;

&lt;p&gt;Use the &lt;code&gt;useSWR&lt;/code&gt; hook in your React component. Pass the key (a unique identifier for your data, such as the API endpoint URL) and the fetcher function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MyComponent() {
  const { data, error } = useSWR('https://api.example.com/data', fetchData);

  if (error) {
    return &amp;lt;div&amp;gt;Error fetching data&amp;lt;/div&amp;gt;;
  }

  if (!data) {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
  }

  // Render your component with the fetched data
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;My Component&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data: {data}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Handle Loading and Errors
&lt;/h3&gt;

&lt;p&gt;Check the &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt; properties returned by &lt;code&gt;useSWR&lt;/code&gt; to handle loading states and errors in your component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;data&lt;/code&gt; is &lt;code&gt;undefined&lt;/code&gt;, it means the data is still being fetched.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;error&lt;/code&gt; is truthy, it means an error occurred during data fetching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optional Step: Customize Configuration
&lt;/h3&gt;

&lt;p&gt;You can customize the behavior of the &lt;code&gt;useSWR&lt;/code&gt; hook by passing an optional configuration object as the third argument. For example, you can set the &lt;code&gt;refreshInterval&lt;/code&gt; to control how often the data should be revalidated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data, error } = useSWR('https://api.example.com/data', fetchData, {
  refreshInterval: 5000, // Refresh every 5 seconds
});

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

&lt;/div&gt;



&lt;p&gt;This is a basic example to get you started. Depending on your use case, you may need to explore more advanced features and configurations provided by the &lt;code&gt;useSWR&lt;/code&gt; hook, such as revalidation, focus revalidation, suspense mode, and more. The official documentation for SWR is a great resource for further details and examples: SWR Documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How automatic caching works in useSWR hook?
&lt;/h2&gt;

&lt;p&gt;Automatic caching is one of the powerful features of the &lt;code&gt;useSWR&lt;/code&gt; hook. Here’s a basic code example illustrating how automatic caching works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Import necessary libraries
import useSWR from 'swr';

// Function to fetch data (replace with your actual API endpoint)
const fetchData = () =&amp;gt; fetch('https://api.example.com/data').then(response =&amp;gt; response.json());

// React component using useSWR for automatic caching
function DataComponent() {
  // Using useSWR with the key (e.g., API endpoint) and the fetcher function
  const { data, error } = useSWR('https://api.example.com/data', fetchData);

  // Loading state
  if (!data &amp;amp;&amp;amp; !error) {
    return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;
  }

  // Error state
  if (error) {
    return &amp;lt;p&amp;gt;Error fetching data: {error.message}&amp;lt;/p&amp;gt;;
  }

  // Render the data
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Data Component&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data: {data}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// Example usage of DataComponent in your main App component
function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Your App&amp;lt;/h1&amp;gt;
      &amp;lt;DataComponent /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;fetchData&lt;/code&gt; function is a placeholder for your actual data-fetching logic. It could be a function that makes an API request and returns the response.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useSWR&lt;/code&gt; is used within the &lt;code&gt;DataComponent&lt;/code&gt; to automatically fetch and cache data. The first parameter is a key that identifies the data, and the second parameter is the fetcher function.&lt;/li&gt;
&lt;li&gt;If the data is not available in the cache, &lt;code&gt;useSWR&lt;/code&gt; triggers the fetcher function (&lt;code&gt;fetchData&lt;/code&gt; in this case) to get the data. Once the data is fetched, it is cached for subsequent requests.&lt;/li&gt;
&lt;li&gt;The component renders loading, error, or data based on the state of the &lt;code&gt;useSWR&lt;/code&gt; hook.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example demonstrates the automatic caching behavior of &lt;code&gt;useSWR&lt;/code&gt;. Subsequent renders of the &lt;code&gt;DataComponent&lt;/code&gt; will use the cached data (if available) without triggering additional network requests unless a revalidation is triggered.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do error handling with useSWR hook?
&lt;/h2&gt;

&lt;p&gt;Error handling is crucial when working with data fetching, and &lt;code&gt;useSWR&lt;/code&gt; provides a convenient way to handle errors. Here’s an example that includes error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Import necessary libraries
import useSWR from 'swr';

// Function to fetch data (replace with your actual API endpoint)
const fetchData = () =&amp;gt; fetch('https://api.example.com/data').then(response =&amp;gt; {
  if (!response.ok) {
    throw new Error('Failed to fetch data');
  }
  return response.json();
});

// React component using useSWR with error handling
function DataComponent() {
  // Using useSWR with the key (e.g., API endpoint) and the fetcher function
  const { data, error } = useSWR('https://api.example.com/data', fetchData);

  // Loading state
  if (!data &amp;amp;&amp;amp; !error) {
    return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;
  }

  // Error state
  if (error) {
    return &amp;lt;p&amp;gt;Error fetching data: {error.message}&amp;lt;/p&amp;gt;;
  }

  // Render the data
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Data Component&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data: {data}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// Example usage of DataComponent in your main App component
function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Your App&amp;lt;/h1&amp;gt;
      &amp;lt;DataComponent /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;fetchData&lt;/code&gt; function is modified to check if the HTTP response is successful (&lt;code&gt;response.ok&lt;/code&gt;). If not, it throws an &lt;code&gt;Error&lt;/code&gt; with a custom message.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;useSWR&lt;/code&gt; hook captures this error, and if an error occurs during the data fetching process, it populates the &lt;code&gt;error&lt;/code&gt; property with information about the error.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;DataComponent&lt;/code&gt; renders an error message if the &lt;code&gt;error&lt;/code&gt; property is truthy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, you can handle errors gracefully in your React components, providing feedback to users when data fetching fails. You can customize the error message and add more sophisticated error-handling logic based on your application’s requirements.&lt;/p&gt;

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

&lt;p&gt;In conclusion, React’s &lt;code&gt;useSWR&lt;/code&gt; hook emerges as a game-changer for simplifying data fetching. With automatic caching, seamless error handling, and a focus on reactivity, &lt;code&gt;useSWR&lt;/code&gt; streamlines the development process. Its real-world applicability and performance benefits make it a must-have tool in the toolkit of React developers. As you dive into using &lt;code&gt;useSWR&lt;/code&gt;, embrace its simplicity, experiment with configurations, and elevate your React applications to new levels of responsiveness and efficiency. Happy coding!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/mastering-data-fetching-with-reacts-useswr-hook/"&gt;Mastering Data Fetching with React’s useSWR Hook&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Exploring the Power of Multiple Instances of the Same Interface in ASP.NET Core</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Wed, 27 Dec 2023 02:19:25 +0000</pubDate>
      <link>https://dev.to/navinkprasad/exploring-the-power-of-multiple-instances-of-the-same-interface-in-aspnet-core-2d5f</link>
      <guid>https://dev.to/navinkprasad/exploring-the-power-of-multiple-instances-of-the-same-interface-in-aspnet-core-2d5f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While ASP.NET Core’s built-in dependency injection brings great ease to development, managing multiple implementations of an interface can be a bit challenging. In this article, I’ll guide you through the process of dynamically selecting a service from various implementations in ASP.NET Core, making the details more accessible for your projects. Let’s dive in and simplify the intricacies together.&lt;/p&gt;

&lt;p&gt;Let’s consider a real-world scenario involving a web application that supports multiple payment gateways. In this example, we’ll create an interface for payment processing and implement different payment gateway providers as separate classes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Visual Studio:&lt;/strong&gt; Ensure you have Visual Studio installed on your machine. You can download Visual Studio from the &lt;a href="https://visualstudio.microsoft.com/"&gt;official Microsoft website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install .NET SDK:&lt;/strong&gt; Make sure you have the .NET SDK installed. You can download it from the official .NET website.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating “ApiGatewayExample” ASP.NET Core WebAPI Project:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open Visual Studio:&lt;/strong&gt; Launch Visual Studio on your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Project:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Click on “Create a new project” or go to &lt;code&gt;File &amp;gt; New &amp;gt; Project...&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select Project Template:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;In the “Create a new project” window, search for “ASP.NET Core Web API”.&lt;/li&gt;
&lt;li&gt;Choose the template labeled “ASP.NET Core Web API” and click “Next.”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure the Project:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Enter “ApiGatewayExample” as the project name.&lt;/li&gt;
&lt;li&gt;Choose a location to save the project and click “Next”&lt;/li&gt;
&lt;li&gt;Select a framework version (.Net 7.0(Standard Term Support)).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure Authentication (Optional):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;If you want to add authentication, you can configure it in this step. For a WebAPI project, you might choose “None” as Authentication Type or configure as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create the Project:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Click “Create” to generate the “ApiGatewayExample” ASP.NET Core WebAPI project.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Adding payment interface and its implementations.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create new folder name “Interfaces” and add “IPaymentGateway.cs” interface as below.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ApiGatewayExample.Interfaces
{
    public interface IPaymentGateway
    {
        string Name { get; }
        bool ProcessPayment(decimal amount);
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create new folder named “Gateway” and add below implemenations in it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PayPalGateway.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ApiGatewayExample.Interfaces;

namespace ApiGatewayExample.Gateway
{
    public class PayPalGateway : IPaymentGateway
    {
        public string Name =&amp;gt; "PayPal";
        public bool ProcessPayment(decimal amount)
        {
            // Implement PayPal payment processing logic
            Console.WriteLine($"Processing {Name} payment: ${amount}");
            // Return success or failure based on the actual implementation
            return true;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;StripeGateway.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ApiGatewayExample.Interfaces;

namespace ApiGatewayExample.Gateway
{
    public class StripeGateway : IPaymentGateway
    {
        public string Name =&amp;gt; "Stripe";
        public bool ProcessPayment(decimal amount)
        {
            // Implement Stripe payment processing logic
            Console.WriteLine($"Processing {Name} payment: ${amount}");
            // Return success or failure based on the actual implementation
            return true;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BraintreeGateway.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ApiGatewayExample.Interfaces;

namespace ApiGatewayExample.Gateway
{
    public class BraintreeGateway : IPaymentGateway
    {
        public string Name =&amp;gt; "Braintree";
        public bool ProcessPayment(decimal amount)
        {
            // Implement Braintree payment processing logic
            Console.WriteLine($"Processing {Name} payment: ${amount}");
            // Return success or failure based on the actual implementation
            return true;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Register Payment Gateways in Dependency Injection Container:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add services to the container.

builder.Services.AddSingleton&amp;lt;IPaymentGateway,PayPalGateway&amp;gt;();
builder.Services.AddSingleton&amp;lt;IPaymentGateway, StripeGateway&amp;gt;();
builder.Services.AddSingleton&amp;lt;IPaymentGateway,BraintreeGateway&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create new Interface “IPaymentProcessor” in interfaces and add below code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ApiGatewayExample.Interfaces
{
    public interface IPaymentProcessor
    {
        bool ProcessPayment(decimal amount, string gatewayName);
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create new class “PaymentProcessor” and add below code in it to retrive the selected payment gateway and process payment using it.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ApiGatewayExample.Interfaces;

namespace ApiGatewayExample
{
    public class PaymentProcessor:IPaymentProcessor
    {
        private readonly IEnumerable&amp;lt;IPaymentGateway&amp;gt; paymentGateways;

        public PaymentProcessor(IEnumerable&amp;lt;IPaymentGateway&amp;gt; paymentGateways)
        {
            this.paymentGateways = paymentGateways;
        }

        private IPaymentGateway GetPaymentGateway(string gatewayName)
        {
            // Retrieve the selected payment gateway instance based on the gatewayName
            return this.paymentGateways.
                FirstOrDefault(gateway =&amp;gt; 
                gateway.Name.Equals(gatewayName, StringComparison.OrdinalIgnoreCase));
        }

        public bool ProcessPayment(decimal amount,string gatewayName)
        {
            IPaymentGateway gateway = GetPaymentGateway(gatewayName);
            if(gateway == null)
            {
                throw new NotImplementedException("Payment Gateway not found for "+ gatewayName);
            }
            return gateway.ProcessPayment(amount);
        }

    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Register PaymentProcessor in DI Container (Program.cs file)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddScoped&amp;lt;IPaymentProcessor,PaymentProcessor&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add new WebAPI Controller named “PaymentController” in Controller folder and update its code as below.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;using ApiGatewayExample.Interfaces;&lt;br&gt;&lt;br&gt;
using Microsoft.AspNetCore.Http;&lt;br&gt;&lt;br&gt;
using Microsoft.AspNetCore.Mvc;&lt;/p&gt;

&lt;p&gt;namespace ApiGatewayExample.Controllers&lt;br&gt;&lt;br&gt;
{&lt;br&gt;&lt;br&gt;
[Route(“api/[controller]”)]&lt;br&gt;&lt;br&gt;
[ApiController]&lt;br&gt;&lt;br&gt;
public class PaymentController : ControllerBase&lt;br&gt;&lt;br&gt;
{&lt;br&gt;&lt;br&gt;
private readonly IPaymentProcessor paymentProcessor;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public PaymentController(IPaymentProcessor paymentProcessor)
    {
        this.paymentProcessor = paymentProcessor;
    }

    [HttpPost]
    public IActionResult ProcessPayment(decimal amount, string selectedPaymentGateway)
    {
        try
        {
            var success= paymentProcessor.ProcessPayment(amount, selectedPaymentGateway);
            return Ok(success ? "Payment successful" : "Payment failed");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            if(ex is NotImplementedException)
            {
                return BadRequest("Gatway not found");
            }

            return StatusCode(500, "Internal Server Error");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Run the project and execute the api in swagger as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2zKnBK-5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-7-1024x521.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2zKnBK-5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-7-1024x521.png" alt="" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kCvPh0ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-8-1024x419.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kCvPh0ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-8-1024x419.png" alt="" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6yUR5uws--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6yUR5uws--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-9.png" alt="" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you can see in above snaps that we are able to select and use the expected implemenatation from the list of multiple implemenatations in asp.net core.&lt;/p&gt;

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

&lt;p&gt;In this exploration of handling multiple implementations in ASP.NET Core’s dependency injection, we’ve uncovered the intricacies of dynamically selecting services. From interfaces and classes to the dynamic processing of payments, our journey through the creation of an “ApiGatewayExample” project has showcased the flexibility and power of ASP.NET Core.&lt;/p&gt;

&lt;p&gt;By implementing interfaces and services, we’ve laid the foundation for a robust API gateway system. The introduction of a &lt;code&gt;PaymentProcessor&lt;/code&gt; class highlighted the seamless integration of specific implementations, providing a glimpse into the extensibility of the ASP.NET Core framework.&lt;/p&gt;

&lt;p&gt;As developers, the ability to manage and utilize various implementations efficiently is a valuable skill. Whether orchestrating complex API interactions or handling payment gateways dynamically, ASP.NET Core empowers us to create versatile and scalable solutions.&lt;/p&gt;

&lt;p&gt;In conclusion, our exploration into ASP.NET Core’s dependency injection world emphasizes not just the technical aspects but also the creative potential it unlocks. As you embark on your own projects, leverage the insights gained here to build systems that are not only functional but also adaptable to the ever-evolving landscape of software development. May your coding endeavors be as dynamic as the services you create in ASP.NET Core.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/aspnet-core-dynamic-service-selection/"&gt;Exploring the Power of Multiple Instances of the Same Interface in ASP.NET Core&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>React Security: Understanding XSS Attacks and the Risks of dangerouslySetInnerHTML</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Sat, 16 Dec 2023 06:57:45 +0000</pubDate>
      <link>https://dev.to/navinkprasad/react-security-understanding-xss-attacks-and-the-risks-of-dangerouslysetinnerhtml-24fi</link>
      <guid>https://dev.to/navinkprasad/react-security-understanding-xss-attacks-and-the-risks-of-dangerouslysetinnerhtml-24fi</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Think of React as the wizard behind interactive websites. But, just like any wizard, it needs protection. This blog is like a shield against a specific danger called Cross-Site Scripting (XSS), especially when using React’s &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Imagine you’re building something cool online, but there’s a sneaky threat. It’s like keeping your door locked against burglars. XSS is a kind of online burglar, and even React needs help staying safe. We’re here to talk about how this threat works and why we need to be careful with &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is dangerouslySetInnerHTML attribute in React.
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; is a specific React attribute that allows you to render HTML content inside a component. The name itself implies that using this attribute can be risky and requires caution.&lt;/p&gt;

&lt;p&gt;Here’s where &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; comes into play. Instead of converting the HTML content into React elements, you can directly set the HTML using this attribute. The “dangerous” part of the name emphasizes that using this attribute can expose your application to Cross-Site Scripting (XSS) attacks if not handled carefully.&lt;/p&gt;

&lt;p&gt;Here’s a basic example of how you might use &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; in a React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MyComponent({ htmlContent }) {
  return &amp;lt;div dangerouslySetInnerHTML={{ __html: htmlContent }} /&amp;gt;;
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Senarios when we might need to use dangerouslySetInnerHTML in React.
&lt;/h2&gt;

&lt;p&gt;There are specific scenarios where using dangerouslySetInnerHTML may be necessary. Here are a few cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rendering HTML from User Input&lt;/strong&gt; :&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;When your application needs to render HTML content provided by users, such as in a comment section or a rich text editor. Ensure that the user input is thoroughly validated and sanitized to mitigate security risks.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Comment({ text }) {
  return &amp;lt;div dangerouslySetInnerHTML={{ __html: text }} /&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Integration with Third-Party Libraries:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Some third-party libraries might generate HTML content that you want to include in your React component. In such cases, you should trust the source of the HTML content and ensure it doesn’t contain malicious code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ThirdPartyIntegration({ htmlContent }) {
  return &amp;lt;div dangerouslySetInnerHTML={{ __html: htmlContent }} /&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Embedding External Widgets or Components:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;If you’re integrating external widgets or components that provide HTML markup, using dangerouslySetInnerHTML might be necessary. Again, ensure that the source is trusted to avoid security issues.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ExternalWidget({ widgetMarkup }) {
  return &amp;lt;div dangerouslySetInnerHTML={{ __html: widgetMarkup }} /&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Rendering Pre-rendered Content:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;When you have pre-rendered HTML content (e.g., from a server or CMS) that needs to be injected into your React component. Ensure the pre-rendered content comes from a trusted source to prevent XSS attacks.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function PreRenderedContent({ htmlContent }) {
  return &amp;lt;div dangerouslySetInnerHTML={{ __html: htmlContent }} /&amp;gt;;
}

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

&lt;/div&gt;



&lt;p&gt;Now as we have understood what is ‘dangerouslySetInnerHTML’ and the situations when we might need to use this. Let us undestand it how to make it secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make it secure?
&lt;/h2&gt;

&lt;p&gt;Below is a sample code which defines a component with a search box input. The input’s value is captured using the &lt;code&gt;useState&lt;/code&gt; hook and displayed in a &lt;code&gt;div&lt;/code&gt;. The &lt;code&gt;onSearchBoxChange&lt;/code&gt; function logs the input value to the console on every change. &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; is used to render the input value in the &lt;code&gt;div&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
function App() {
  const [value, setValue] = React.useState("");
  function onSearchBoxChange(e: any) {
    e.preventDefault();
    setValue(e.target.value);
    console.log(e.target.value);
  }

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;input type="text" name="searchBox" onChange={onSearchBoxChange}&amp;gt;&amp;lt;/input&amp;gt;
      &amp;lt;div
        dangerouslySetInnerHTML={{
          __html: value,
        }}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;When we run this and try to put some script in text box , it logs it on console and inject it on browser too. you can see in below screen shots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ouu1bSti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ouu1bSti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-3.png" alt="" width="773" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--47HTP945--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--47HTP945--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-4.png" alt="" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In above you can see that script tag is injected which we do not want to be there. so lets us see how we can solve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  DOMPurify package.
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;DOMPurify&lt;/code&gt; is a JavaScript library that provides a way to sanitize and clean up HTML content, making it safe to use in your web applications. Its primary purpose is to prevent Cross-Site Scripting (XSS) vulnerabilities by removing or neutralizing potentially harmful code from user-generated or external HTML content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install DOMPurify package
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install dompurify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using TypeScript then you also need to install its type definition using below command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --save-dev @types/dompurify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next update the above sample code to use DOMPurify package and sanatize the input coming from user as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import DOMPurify from "dompurify";
function App() {
  const [value, setValue] = React.useState("");
  function onSearchBoxChange(e: any) {
    e.preventDefault();
    const purifiedValue = DOMPurify.sanitize(e.target.value);
    setValue(purifiedValue);
    console.log(purifiedValue);
  }

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;input type="text" name="searchBox" onChange={onSearchBoxChange}&amp;gt;&amp;lt;/input&amp;gt;
      &amp;lt;div
        dangerouslySetInnerHTML={{
          __html: value,
        }}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;Now let use see how it looks with the same input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m8YBXaGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m8YBXaGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-5.png" alt="" width="792" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lEoI-03X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lEoI-03X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-6.png" alt="" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that it prevented the injection of script code in div example here. This is how you can prevent dangerous input like script to be injected in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this blog, we delved into the world of React security, specifically focusing on the &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; attribute and the potential risks associated with Cross-Site Scripting (XSS). We began by drawing an analogy between React and a wizard, highlighting the need for a shield to protect against online burglars, where XSS acts as a stealthy threat.&lt;/p&gt;

&lt;p&gt;Exploring the purpose and risks of &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;, we identified scenarios where it becomes necessary, such as rendering user input, integrating third-party libraries, embedding external components, and handling pre-rendered content. The blog then introduced DOMPurify as a potent defense mechanism, demonstrating its integration to sanitize user inputs effectively.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mind the Wizard’s Shield:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;React, akin to a wizard, requires a shield against online threats. Recognizing and addressing vulnerabilities is paramount for safeguarding applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understanding &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This React attribute allows rendering HTML content but demands caution due to its potential security risks, especially with XSS attacks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenarios for Caution:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;User input, third-party integrations, external components, and pre-rendered content are scenarios where &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; might be needed, but careful handling is crucial.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enter DOMPurify:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;DOMPurify emerges as a robust solution to mitigate XSS risks. Its integration ensures sanitized user inputs, bolstering the security of React applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Vigilance:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Web security is an ongoing commitment. Regular updates, awareness of emerging threats, and adherence to best practices are vital for maintaining a resilient defense.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In conclusion, this blog equips developers with insights into React security, offering practical solutions to fortify applications against potential vulnerabilities. By embracing secure coding practices and staying vigilant, developers can confidently navigate the dynamic landscape of web development, ensuring both functionality and user safety.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/react-security-understanding-xss-attacks-and-the-risks-of-dangerouslysetinnerhtml/"&gt;React Security: Understanding XSS Attacks and the Risks of dangerouslySetInnerHTML&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactsecurity</category>
      <category>xss</category>
    </item>
    <item>
      <title>Unlocking Seamless Data Sharing: A Deep Dive into React Router v6 and Context for Multi-Page Dashboards</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Fri, 15 Dec 2023 04:02:56 +0000</pubDate>
      <link>https://dev.to/navinkprasad/unlocking-seamless-data-sharing-a-deep-dive-into-react-router-v6-and-context-for-multi-page-dashboards-233p</link>
      <guid>https://dev.to/navinkprasad/unlocking-seamless-data-sharing-a-deep-dive-into-react-router-v6-and-context-for-multi-page-dashboards-233p</guid>
      <description>&lt;p&gt;&lt;strong&gt;Imagine this:&lt;/strong&gt; You’re building a multi-page dashboard. Each page needs access to user information, but traditional prop drilling makes your code spaghetti-like. Enter context! We’ll leverage React’s built-in context API to effortlessly inject props into Outlet and seamlessly share them across your child components, all while maintaining clean and maintainable code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introducing Outlet Context: The Superhero of Data Sharing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enter the mighty &lt;strong&gt;outlet&lt;/strong&gt;  &lt;strong&gt;context API&lt;/strong&gt; , built-in to React Router V6. Think of it as a magic portal that seamlessly transports data between components, regardless of their nesting level. With context, you can share global state, user information, and any other data you need, all without prop drilling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Magic of Outlet Context and Outlet Props&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Router v6 comes with a powerful component called &lt;code&gt;Outlet&lt;/code&gt;. It acts as a placeholder for child routes, rendering the content they define. But here’s the exciting part: you can leverage context to inject props into &lt;code&gt;Outlet&lt;/code&gt;, making them accessible to all its child components!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of Passing Props to Outlet with Context:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean and maintainable code:&lt;/strong&gt;  Ditch the prop drilling spaghetti and structure your code like a well-organized garden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved data sharing:&lt;/strong&gt;  Share data effortlessly across any level of nested components, keeping your state management centralized and efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced flexibility:&lt;/strong&gt;  Dynamically change props based on routes or user interactions, adding a whole new level of control to your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced boilerplate code:&lt;/strong&gt;  No more prop drilling rituals! Context takes care of data flow, leaving you with more time to focus on building amazing features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let’s Dive in: A Step-by-Step Guide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an react app named “outlet-context-example” with typescript as template using below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app outlet-context-example --template typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now open the project in vs code and install the react-router dom package as below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0NL3Yurm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0NL3Yurm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image.png" alt="" width="800" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a components folder in src and then create “ChildComponent1.tsx”, “ChildComponent2.tsx”, “ChildComponent3.tsx” and HomeDashboard.tsx file in component folder as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--20lI5ePd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--20lI5ePd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-1.png" alt="Illustration: Data Flow Using React Context API in Multi-Page React Router v6" width="509" height="808"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next Update the App.tsx file with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { RouterProvider, createBrowserRouter } from "react-router-dom";
import HomeDashboard from "./components/HomeDashboard";
import ChildComponent1 from "./components/ChildComponent1";
import ChildComponent2 from "./components/ChildComponent2";
import ChildComponent3 from "./components/ChildComponent3";

const routes = createBrowserRouter([
  {
    path: "/",
    element: &amp;lt;HomeDashboard /&amp;gt;,
    children: [
      {
        path: "component1",
        element: &amp;lt;ChildComponent1 /&amp;gt;,
      },
      {
        path: "component2",
        element: &amp;lt;ChildComponent2 /&amp;gt;,
      },
      {
        path: "component3",
        element: &amp;lt;ChildComponent3 /&amp;gt;,
      },
    ],
  },
]);

function App() {
  return &amp;lt;RouterProvider router={routes} /&amp;gt;;
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;The above code uses the &lt;code&gt;react-router-dom&lt;/code&gt; library for handling navigation. It defines a set of routes, including a main route (“/”) that renders a &lt;code&gt;HomeDashboard&lt;/code&gt; component and three child routes (“component1,” “component2,” and “component3”) that render corresponding child components (&lt;code&gt;ChildComponent1&lt;/code&gt;, &lt;code&gt;ChildComponent2&lt;/code&gt;, and &lt;code&gt;ChildComponent3&lt;/code&gt;). The &lt;code&gt;App&lt;/code&gt; component serves as the main entry point and utilizes the &lt;code&gt;RouterProvider&lt;/code&gt; from &lt;code&gt;react-router-dom&lt;/code&gt; to provide routing information to the rest of the application.&lt;/p&gt;

&lt;p&gt;Update Homedashboard.tsx with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Outlet, useNavigate, useOutletContext } from "react-router-dom";

const sampleServerData = {
  employeeInfo: {
    id: 1,
    name: "John",
  },
};

type EmployeeInfoContextType = {
  empInfo: {
    id: number;
    name: string;
  };
};

function HomeDashboard() {
  const navigate = useNavigate();
  function loadComponent1(e: any) {
    e.preventDefault();
    navigate("/component1");
  }

  function loadComponent2(e: any) {
    e.preventDefault();
    navigate("/component2");
  }
  function loadComponent3(e: any) {
    e.preventDefault();
    navigate("/component3");
  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;Header area&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={loadComponent1}&amp;gt;Load Component1&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={loadComponent2}&amp;gt;Load Component2&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={loadComponent3}&amp;gt;Load Component3&amp;lt;/button&amp;gt;
      &amp;lt;Outlet
        context={{
          empInfo: sampleServerData.employeeInfo,
        }}
      /&amp;gt;
      &amp;lt;footer&amp;gt;footer area&amp;lt;/footer&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export function useEmployeeInfoData(): EmployeeInfoContextType {
  return useOutletContext&amp;lt;EmployeeInfoContextType&amp;gt;();
}

export default HomeDashboard;

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

&lt;/div&gt;



&lt;p&gt;The above code defines a React component named &lt;code&gt;HomeDashboard&lt;/code&gt;, representing a dashboard with navigation buttons and an outlet for rendering child components. Here’s a succinct breakdown:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigation and Outlet:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The component uses buttons (&lt;code&gt;Load Component1&lt;/code&gt;, &lt;code&gt;Load Component2&lt;/code&gt;, &lt;code&gt;Load Component3&lt;/code&gt;) to trigger navigation to different routes using the &lt;code&gt;react-router-dom&lt;/code&gt; library.&lt;/li&gt;
&lt;li&gt;It employs the &lt;code&gt;Outlet&lt;/code&gt; component to specify where child components will be rendered.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context and Data:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A sample data structure (&lt;code&gt;sampleServerData&lt;/code&gt;) simulates employee information.&lt;/li&gt;
&lt;li&gt;A context type (&lt;code&gt;EmployeeInfoContextType&lt;/code&gt;) is defined to represent the structure of employee information.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functions and Footer:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;useNavigate&lt;/code&gt; hook is used to navigate to different components when buttons are clicked.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;useEmployeeInfoData&lt;/code&gt; function is exported for child components to access the employee information context.&lt;/li&gt;
&lt;li&gt;The component includes a header, buttons for navigation, an outlet for child components, and a footer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This setup provides a structured and navigable interface for a React application, and the use of context allows for the efficient sharing of data between components. This blog post can delve deeper into the importance of routing, context, and component composition in building maintainable and scalable React applications.The &lt;code&gt;useEmployeeInfoData&lt;/code&gt; hook uses &lt;code&gt;useOutletContext&lt;/code&gt; from &lt;code&gt;react-router-dom&lt;/code&gt; to access the shared context, ensuring consistent data retrieval across child components.&lt;/p&gt;

&lt;p&gt;Update ChildComponent1.tsx with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEmployeeInfoData } from "./HomeDashboard";

function ChildComponent1() {
  const empInfoData = useEmployeeInfoData();
  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;Child Component 1 loaded&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Employee Info:&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt; id:{empInfoData.empInfo.id}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;name: {empInfoData.empInfo.name}&amp;lt;/p&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default ChildComponent1;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ChildComponent1&lt;/code&gt; is a React component that leverages the &lt;code&gt;useEmployeeInfoData&lt;/code&gt; function from the &lt;code&gt;HomeDashboard&lt;/code&gt; module. This component displays a simple user interface with a heading indicating its loaded status and paragraph elements showcasing employee information such as ID and name. The use of context allows &lt;code&gt;ChildComponent1&lt;/code&gt; to seamlessly access and present data shared by its parent component (&lt;code&gt;HomeDashboard&lt;/code&gt;). This coding structure demonstrates the efficiency of React context for managing and passing data across different parts of a React application.&lt;/p&gt;

&lt;p&gt;Update ChildComponent2.tsx with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEmployeeInfoData } from "./HomeDashboard";

function ChildComponent2() {
  const empInfoData = useEmployeeInfoData();
  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;Child Component 2 loaded&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Employee Info:&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt; id:{empInfoData.empInfo.id}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;name: {empInfoData.empInfo.name}&amp;lt;/p&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default ChildComponent2;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ChildComponent2&lt;/code&gt; is another React component that relies on the &lt;code&gt;useEmployeeInfoData&lt;/code&gt; function imported from the &lt;code&gt;HomeDashboard&lt;/code&gt; module. Like its counterpart, &lt;code&gt;ChildComponent1&lt;/code&gt;, it renders a user interface indicating its loaded status and displays employee information retrieved from the shared context. This consistent approach highlights the modularity and ease of data sharing facilitated by React’s context management.&lt;/p&gt;

&lt;p&gt;Update ChildComponent3.tsx with below code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEmployeeInfoData } from "./HomeDashboard";

function ChildComponent3() {
  const empInfoData = useEmployeeInfoData();
  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;Child Component 3 loaded&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Employee Info:&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt; id:{empInfoData.empInfo.id}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;name: {empInfoData.empInfo.name}&amp;lt;/p&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default ChildComponent3;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ChildComponent3&lt;/code&gt; is a React component that leverages the &lt;code&gt;useEmployeeInfoData&lt;/code&gt; function from the &lt;code&gt;HomeDashboard&lt;/code&gt; module, emphasizing the shared employee information context. Following a similar structure to its counterparts, this component displays a loaded status, along with employee information (ID and name) retrieved from the context. The uniformity in approach across these child components highlights the efficiency and simplicity of React’s context management for data sharing in a modular and maintainable manner.&lt;/p&gt;

&lt;p&gt;This is the running application output on browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---2oeO0cW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---2oeO0cW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/12/image-2.png" alt="" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In the ever-evolving landscape of React development, React Router v6 stands out as a powerful ally for efficient navigation and state management. The journey we’ve embarked upon in this blog has unraveled the complexities of traditional prop drilling and illuminated a path paved with the simplicity of React’s context API.&lt;/p&gt;

&lt;p&gt;As we conclude, let’s reflect on the key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner and Maintainable Code:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;By bidding farewell to the tangled web of prop drilling, we’ve embraced a coding style that resembles a well-organized garden—structured, readable, and easy to maintain.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effortless Data Sharing:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The introduction of the Outlet context API serves as our superhero, effortlessly transporting data between components. This seamless sharing mechanism ensures that data flows harmoniously across various nested levels.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility in Prop Passing:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;React Router v6, with its Outlet and context combination, provides a dynamic approach to prop passing. React to route changes or user interactions by adjusting props, adding a newfound level of control and flexibility to your application.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boilerplate Code Reduction:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The era of prop drilling rituals has come to an end. With context gracefully handling data flow, developers can now allocate more time to crafting remarkable features rather than wrestling with boilerplate code.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;As you integrate these practices into your React projects, consider the profound impact on the scalability, readability, and overall developer experience. React Router v6, armed with the Outlet context API, empowers you to build applications that are not just functional but also elegantly structured.&lt;/p&gt;

&lt;p&gt;So, go ahead, dive into the world of React Router v6, wield the Outlet context API, and let your code flourish with the simplicity and efficiency it deserves. Happy coding!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/react-router-v6-easily-pass-props-to-outlet-with-context/"&gt;Unlocking Seamless Data Sharing: A Deep Dive into React Router v6 and Context for Multi-Page Dashboards&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>context</category>
      <category>reactrouter</category>
    </item>
    <item>
      <title>𝐘𝐨𝐮𝐫 𝐈𝐦𝐩𝐞𝐫𝐟𝐞𝐜𝐭𝐢𝐨𝐧 𝐢𝐬 𝐘𝐨𝐮𝐫 𝐀𝐮𝐭𝐡𝐞𝐧𝐭𝐢𝐜𝐢𝐭𝐲</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Thu, 05 Oct 2023 06:24:55 +0000</pubDate>
      <link>https://dev.to/navinkprasad/-261f</link>
      <guid>https://dev.to/navinkprasad/-261f</guid>
      <description>&lt;p&gt;In the professional world, there's often a tendency for individuals to project an image of perfection. We strive to talk perfectly, walk perfectly, and present our work as flawless. However, the pursuit of constant perfection can sometimes feel artificial, like an impeccably crafted artificial flower that remains unchanged regardless of the weather conditions.&lt;/p&gt;

&lt;p&gt;But in reality, people are drawn to authenticity. They want to see the real truth rather than a facade. Over time, people gravitate towards those who are real, those who show the ups and downs of life. It's perfectly okay not to be perfect all the time. It's okay to acknowledge and even celebrate your imperfections. It's okay to showcase works in progress alongside your well-completed projects. It's okay to discuss the challenges you're facing, even when it seems like nobody else wants to talk about them.&lt;/p&gt;

&lt;p&gt;The swagger of showmanship may get attention initially, but it rarely sustains in the long run because it lacks authenticity. Over time, people tend to appreciate and respect those who are genuine and who show the real picture, warts and all.&lt;/p&gt;

&lt;p&gt;In fact, the Japanese tradition of wabi-sabi beautifully embodies this philosophy. Wabi-sabi celebrates the beauty found in imperfections, impermanence, and simplicity. It reminds us that authenticity and the acknowledgment of our flaws can be profoundly powerful in both our personal and professional lives.&lt;/p&gt;

&lt;p&gt;So, remember that your imperfections are making you unique and authentic. Embrace them, share your journey, and watch as people connect with you on a deeper level because you're genuine and real.&lt;/p&gt;

&lt;p&gt;If you like such post, follow me for more.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing Code Splitting in React for Improved Performance</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Sat, 30 Sep 2023 07:55:07 +0000</pubDate>
      <link>https://dev.to/navinkprasad/implementing-code-splitting-in-react-for-improved-performance-3465</link>
      <guid>https://dev.to/navinkprasad/implementing-code-splitting-in-react-for-improved-performance-3465</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In today’s fast-paced digital landscape, where users demand lightning-fast experiences, web developers face a pressing challenge: how to create web applications that are not only feature-rich but also load quickly. When it comes to React applications, one powerful technique that can significantly enhance performance is code splitting.&lt;/p&gt;

&lt;p&gt;Imagine this scenario: You’re building a large-scale React application with numerous components, libraries, and features. Traditionally, all of your JavaScript code is bundled into a single massive file. As a result, when a user lands on your site, they have to wait for this behemoth of a bundle to download and execute before they can interact with your app. This can lead to frustratingly long loading times, especially on slower connections or less powerful devices.&lt;/p&gt;

&lt;p&gt;This is where code splitting comes to the rescue. Code splitting is a strategy that allows you to break down your application’s JavaScript bundle into smaller, more manageable pieces. Instead of loading everything upfront, you can load only the code that’s necessary for the current user’s journey through your app. This not only dramatically reduces the initial load time but also optimizes the overall performance of your React application.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore the concept of code splitting in React and dive into various techniques and best practices for its implementation. Whether you’re working on a massive enterprise-level application or a smaller project, understanding code splitting can be a game-changer for your development workflow and user experience. So, let’s embark on this journey to harness the power of code splitting and ensure that your React applications are not just feature-rich but also blazingly fast. Let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set Up Your Development Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you start, make sure you have Node.js and npm (Node Package Manager) installed on your system. You can download them from the official website if you haven’t already.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a New React Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your terminal and run the following command to create a new React project with Create React App:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app code-splitting-example

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

&lt;/div&gt;



&lt;p&gt;Once you the above command completes, you may have the output similar to below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IUzCT4wN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-60-1024x567.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IUzCT4wN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-60-1024x567.png" alt="" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Navigate to Your Project Directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to your project directory using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd code-splitting-example

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Open the project directory in vscode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the project directory in vscode using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;code .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the project structure as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3_D03vot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3_D03vot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-61.png" alt="" width="427" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create Some Sample Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this step, you can create some sample components that you’ll later split into separate bundles. For example, let’s create “components” directory in src and then create two components named &lt;code&gt;Home.js&lt;/code&gt; and &lt;code&gt;About.js&lt;/code&gt; inside a &lt;code&gt;components&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;Create and update &lt;code&gt;src/components/Home.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

function Home() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Welcome to the Home Page!&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Home;

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

&lt;/div&gt;



&lt;p&gt;Create and update &lt;code&gt;src/components/About.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

function About() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;About Us&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;We are a passionate team of developers.&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default About;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Create a Sample Routing Structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-router-dom

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

&lt;/div&gt;



&lt;p&gt;You should see similar output as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zqICHgZe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zqICHgZe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-62.png" alt="" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, create a simple routing structure. Edit &lt;code&gt;src/App.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';

function App() {
  return (
    &amp;lt;Router&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;nav&amp;gt;
          &amp;lt;ul&amp;gt;
            &amp;lt;li&amp;gt;
              &amp;lt;Link to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
            &amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;
              &amp;lt;Link to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
            &amp;lt;/li&amp;gt;
          &amp;lt;/ul&amp;gt;
        &amp;lt;/nav&amp;gt;

        &amp;lt;hr /&amp;gt;

        &amp;lt;Route exact path="/" component={Home} /&amp;gt;
        &amp;lt;Route path="/about" component={About} /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/Router&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Implement Code Splitting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To implement code splitting, we can use the &lt;code&gt;React.lazy()&lt;/code&gt; function. Modify &lt;code&gt;src/App.js&lt;/code&gt; to use &lt;code&gt;React.lazy()&lt;/code&gt; for loading the components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom';

const Home = lazy(() =&amp;gt; import('./components/Home'));
const About = lazy(() =&amp;gt; import('./components/About'));

function App() {
  return (
    &amp;lt;Router&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;nav&amp;gt;
          &amp;lt;ul&amp;gt;
            &amp;lt;li&amp;gt;
              &amp;lt;Link to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
            &amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;
              &amp;lt;Link to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
            &amp;lt;/li&amp;gt;
          &amp;lt;/ul&amp;gt;
        &amp;lt;/nav&amp;gt;
        &amp;lt;hr /&amp;gt;
        &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}&amp;gt;
          &amp;lt;Routes&amp;gt;
            &amp;lt;Route path="/" element={&amp;lt;Home /&amp;gt;} /&amp;gt;
            &amp;lt;Route path="/about" element={&amp;lt;About /&amp;gt;} /&amp;gt;
          &amp;lt;/Routes&amp;gt;
        &amp;lt;/Suspense&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/Router&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7: Start the Development Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’re all set! Now, start your development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start

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

&lt;/div&gt;



&lt;p&gt;This will launch your React application, and you can navigate between the “Home” and “About” pages. Code splitting is automatically applied, and each component will be loaded on-demand when you access its respective route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bmHYnVrd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-63-1024x643.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bmHYnVrd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-63-1024x643.png" alt="" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ve now created a simple React project named “code-splitting-example” that demonstrates code splitting using React.lazy() and React Router. You can expand on this project by adding more components and experimenting with different code splitting scenarios to showcase its benefits further.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the fast-paced world of web development, optimizing React applications for speed and responsiveness is essential. Code splitting offers a powerful solution. It breaks down the JavaScript bundle into smaller parts, loading only what’s needed for improved performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Splitting Benefits:&lt;/strong&gt; Code splitting reduces initial load times, making web applications more responsive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to Use It:&lt;/strong&gt; Code splitting is ideal for large apps, complex routing, and dynamic imports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Techniques:&lt;/strong&gt; We explored dynamic imports with &lt;code&gt;import()&lt;/code&gt; and how to use &lt;code&gt;React.lazy()&lt;/code&gt; with &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; for code splitting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Practices:&lt;/strong&gt; Follow component grouping, Webpack optimization, and error handling for effective code splitting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code splitting empowers developers to strike the right balance between feature-rich applications and exceptional performance, delivering an elevated user experience.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/react-code-splitting-improve-performance/"&gt;Implementing Code Splitting in React for Improved Performance&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Enhancing Reliability: Global Exception Handling in ASP.NET Core Web APIs</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Fri, 29 Sep 2023 12:31:21 +0000</pubDate>
      <link>https://dev.to/navinkprasad/enhancing-reliability-global-exception-handling-in-aspnet-core-web-apis-adl</link>
      <guid>https://dev.to/navinkprasad/enhancing-reliability-global-exception-handling-in-aspnet-core-web-apis-adl</guid>
      <description>&lt;p&gt;In today’s digital landscape, the demand for robust and reliable web APIs is ever-growing. Whether you’re developing a RESTful service, a microservice, or a full-fledged web application, handling exceptions gracefully is a fundamental aspect of ensuring your API’s stability and usability. After all, the real world is far from perfect, and unexpected errors can occur at any time.&lt;/p&gt;

&lt;p&gt;Imagine this scenario: You’ve built a sophisticated ASP.NET Core Web API, and everything seems to be running smoothly. Users are interacting with your application, but suddenly, an unhandled exception disrupts the flow, resulting in a confusing error message or, even worse, a crash. How can you prevent such mishaps and deliver a seamless experience to your users?&lt;/p&gt;

&lt;p&gt;Enter global exception handling in ASP.NET Core, a powerful mechanism that allows you to intercept and manage exceptions at a central level within your application. This approach ensures that no matter where an exception originates—be it in your controller actions, middleware, or service layer—it can be caught, processed, and transformed into a clear, consistent error response.&lt;/p&gt;

&lt;p&gt;In this blog post, we will delve into the world of global exception handling in ASP.NET Core Web APIs. We’ll explore the concept, its significance, and most importantly, how to implement it effectively in your projects. By the end of this journey, you’ll have the tools and knowledge needed to fortify your APIs against unexpected errors, enhance user experiences, and maintain the reputation of your application’s reliability.&lt;/p&gt;

&lt;p&gt;So, let’s embark on this journey of learning how to build resilient ASP.NET Core Web APIs by mastering the art of global exception handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up an ASP.NET Core Web API Project
&lt;/h2&gt;

&lt;p&gt;To get started with learning about global exception handling in ASP.NET Core Web APIs, let’s create a sample project. Follow these steps to set up a new ASP.NET Core Web API project using Visual Studio:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Launch Visual Studio&lt;/strong&gt; : Open Visual Studio on your development machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Project&lt;/strong&gt; : Navigate to the “File” menu, select “New,” and then choose “Project…” from the dropdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select the Project Template&lt;/strong&gt; : In the “Create a new project” window, locate and select the “ASP.NET Core Web API” project template. This template is tailored for building RESTful Web APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure Project Settings&lt;/strong&gt; : Provide a meaningful name for your project, such as “ &lt;strong&gt;ExceptionHandlingDemo&lt;/strong&gt; ,” and specify the project’s location. Additionally, choose the target framework version. Typically, ASP.NET Core projects use the latest LTS (Long-Term Support) version of the .NET Core framework for stability and long-term compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional: Authentication and Authorization&lt;/strong&gt; : Depending on your project’s security requirements, you can configure authentication and authorization settings during project creation. For instance, you might opt to implement JWT (JSON Web Tokens) authentication to secure your API endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create the Project&lt;/strong&gt; : Click the “Create” button to initiate the creation of your ASP.NET Core Web API project with the specified settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Adding Exception Handling to the WeatherForecastController
&lt;/h2&gt;

&lt;p&gt;Now that we have our ASP.NET Core Web API project set up, let’s focus on enhancing the error-handling capabilities of our API by implementing exception handling within the “WeatherForecastController.” Additionally, we’ll take advantage of the async-await pattern to improve responsiveness and scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Async-Await in ASP.NET Core Web APIs
&lt;/h3&gt;

&lt;p&gt;In modern ASP.NET Core Web APIs, asynchronous programming using &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; is essential for handling I/O-bound operations efficiently. The async-await pattern allows your API to remain responsive while waiting for time-consuming tasks to complete, such as accessing a database or making external API requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated GET Method
&lt;/h3&gt;

&lt;p&gt;Here’s an updated version of the &lt;code&gt;GET&lt;/code&gt; method within the “WeatherForecastController” that incorporates async-await:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        [HttpGet(Name = "GetWeatherForecast")]
        public async Task&amp;lt;ActionResult&amp;lt;IEnumerable&amp;lt;WeatherForecast&amp;gt;&amp;gt;&amp;gt; Get()
        {
            try
            {
                return await Task.WhenAll(
                    Enumerable.Range(1, 5).Select(async index =&amp;gt; new WeatherForecast
                    {
                        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                        TemperatureC = await Task.Run(() =&amp;gt; Random.Shared.Next(-20, 55)), // Simulate async operation
                        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                    })
                );

            }
            catch (Exception ex)
            {
                // Log the exception (you can use a logging framework like Serilog or NLog)
                Console.WriteLine($"An error occurred: {ex}");

                return StatusCode(StatusCodes.Status500InternalServerError, "something went wrong");
            }

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

&lt;/div&gt;



&lt;p&gt;In this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We continue to use the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; keywords to ensure non-blocking execution, especially when performing potentially time-consuming operations.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Task.WhenAll&lt;/code&gt; method is used to asynchronously generate weather forecasts. We generate forecasts for the next 5 days, simulating this as an asynchronous operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exception Handling
&lt;/h3&gt;

&lt;p&gt;Exception handling remains a pivotal aspect of our API’s reliability. Here’s how we handle exceptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside the &lt;code&gt;try&lt;/code&gt; block, we attempt to generate weather forecasts. If an exception occurs during this process, it’s caught by the &lt;code&gt;catch&lt;/code&gt; block.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;catch&lt;/code&gt; block, we log the exception using &lt;code&gt;Console.WriteLine&lt;/code&gt;. In a production environment, it’s recommended to use a dedicated logging framework like Serilog or NLog for comprehensive error logging.&lt;/li&gt;
&lt;li&gt;We return a &lt;code&gt;500 Internal Server Error&lt;/code&gt; status code (&lt;code&gt;StatusCodes.Status500InternalServerError&lt;/code&gt;) along with a user-friendly error message, “Something went wrong.” This provides meaningful feedback to the client while not exposing sensitive error details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now run the project and execute on swagger, you should see similar output as below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i_mEBNx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-52-1024x726.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i_mEBNx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-52-1024x726.png" alt="" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;let’s introduce intentional errors into the &lt;code&gt;try&lt;/code&gt; block of the &lt;code&gt;Get&lt;/code&gt; method to simulate real-world scenarios where errors can occur. Here’s the updated code with simulated errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try
{
    throw new Exception("Some error occured!");
    return await Task.WhenAll(
        Enumerable.Range(1, 5).Select(async index =&amp;gt; new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = await Task.Run(() =&amp;gt; Random.Shared.Next(-20, 55)), // Simulate async operation
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
    );

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

&lt;/div&gt;



&lt;p&gt;Next run the application and call the same api, you should see output as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ku1zyN5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ku1zyN5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-53.png" alt="" width="800" height="757"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;here you can see we are getting the response 500 and the message which we set in catch block. The actual exception is logged in console as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pFxLqvrl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-54-1024x89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pFxLqvrl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-54-1024x89.png" alt="" width="800" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the code provided, we’re returning a &lt;code&gt;500 Internal Server Error&lt;/code&gt; response to the client along with a user-friendly error message, “Something went wrong,” while logging the actual exception to the console. This is a common practice in web APIs to provide a meaningful error response to clients while keeping detailed error information for debugging and monitoring purposes.&lt;/p&gt;

&lt;p&gt;We can certainly improve our error handling by incorporating unique identifiers for each error and implementing code to log exceptions in databases or log files. These steps are valuable.&lt;/p&gt;

&lt;p&gt;However, a significant challenge arises when dealing with multiple APIs. Do we really need to update the code of each API individually and insert try-catch blocks? And what if we need to modify the exception response—would that mean altering the response for every API’s catch block?&lt;/p&gt;

&lt;p&gt;These are substantial concerns, and if we answer ‘yes’ to these questions, it could consume a substantial amount of development time. This may not be the most efficient use of our resources. So, what is the solution?&lt;/p&gt;

&lt;p&gt;The solution is adding global exception handling. Let us see how we can use it.&lt;/p&gt;

&lt;p&gt;Add a new folder “Middleware” and a new class file “ExceptionHandler” in it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h0aA4Fqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h0aA4Fqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-55.png" alt="" width="488" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the “ExceptionHandler” file code as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ExceptionHandlingDemo.Middleware
{
    public class ExceptionHandler
    {
        private readonly ILogger&amp;lt;ExceptionHandler&amp;gt; logger;
        private readonly RequestDelegate request;

        public ExceptionHandler(ILogger&amp;lt;ExceptionHandler&amp;gt; logger, RequestDelegate request)
        {
            this.logger = logger;
            this.request = request;
        }

        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await request(httpContext);
            }
            catch (Exception ex)
            {
                // Generate a new GUID to log and send to client so that we able
                // to match the error with details exception
                var exceptionId = Guid.NewGuid().ToString();

                //log the details exception

                logger.LogError(ex, "ExceptionId:" + exceptionId, "Message:" + ex.Message);

                // return the custom exception to client 

                httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
                httpContext.Response.ContentType = "application/json";

                await httpContext.Response.WriteAsJsonAsync(new
                {
                    Id = exceptionId,
                    error = "Some Internal error occured while processing the request"
                });
            }
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;The above code demonstrates the creation of custom exception handling middleware for ASP.NET Core applications. This middleware intercepts and handles exceptions that occur during the processing of HTTP requests, ensuring consistent error responses.&lt;/p&gt;

&lt;p&gt;Key Points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;ExceptionHandler&lt;/code&gt; class resides in the &lt;code&gt;ExceptionHandlingDemo.Middleware&lt;/code&gt; namespace.&lt;/li&gt;
&lt;li&gt;It accepts an &lt;code&gt;ILogger&lt;/code&gt; for logging and a &lt;code&gt;RequestDelegate&lt;/code&gt; to pass the request along.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;InvokeAsync&lt;/code&gt; method, exceptions are caught, logged with unique identifiers, and sent as structured JSON responses to clients.&lt;/li&gt;
&lt;li&gt;This middleware promotes better error management and a standardized approach to handling exceptions across your ASP.NET Core application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now our Exception handling middleware is ready , next we need to inject this so that the framework knows about it.&lt;/p&gt;

&lt;p&gt;add below line of code in program.cs file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.UseMiddleware&amp;lt;ExceptionHandler&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F4qBoh5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F4qBoh5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-56.png" alt="" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now comment out or remove try catch handling in the WeatherForecastController GET method. The method should be like below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JEYSNeea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-57-1024x445.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JEYSNeea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-57-1024x445.png" alt="" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code on line 26 simulates the occurrence of an exception during the processing of an API request. To observe this behavior in action, run the application and then make a request to the API. You should expect the following output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0sX-2ID7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-58-1024x699.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0sX-2ID7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-58-1024x699.png" alt="" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The response includes an &lt;code&gt;Id&lt;/code&gt; field, which serves as a unique identifier for the error. This identifier can be used to retrieve detailed information about the specific error. Additionally, the code employs a logger to record exception details, which are typically logged to the console by default. Below, you can find an example of the console output, showcasing the logged error information:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8417X-Ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-59-1024x505.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8417X-Ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-59-1024x505.png" alt="" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can observe, the response contains an &lt;code&gt;Id&lt;/code&gt; field, which is a unique identifier for the error. This identifier remains consistent between the logged error details and the response, making it convenient for associating errors.&lt;/p&gt;

&lt;p&gt;To further enhance error management, consider extending the logging functionality beyond console output. You can customize the logging mechanism to store error information in a database, text file, or any other suitable storage medium. This approach ensures comprehensive error tracking and facilitates thorough analysis and troubleshooting.&lt;/p&gt;

&lt;p&gt;This is how we can implement the Global exception handling in asp.net core Web APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this blog post, we’ve explored the implementation of custom exception handling middleware in ASP.NET Core applications. This middleware intercepts exceptions globally, ensuring consistent and user-friendly error responses. Key takeaways include setting up the middleware, handling exceptions, and the flexibility of logging. By adopting such middleware, ASP.NET Core applications can maintain a uniform approach to error management, enhancing overall reliability and maintainability.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/global-exception-handling-aspnet-core-web-apis/"&gt;Enhancing Reliability: Global Exception Handling in ASP.NET Core Web APIs&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>uncategorized</category>
    </item>
    <item>
      <title>My Top 5 learning from the Book “REWORK”</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Thu, 28 Sep 2023 17:43:09 +0000</pubDate>
      <link>https://dev.to/navinkprasad/my-top-5-learning-from-the-book-rework-4cp8</link>
      <guid>https://dev.to/navinkprasad/my-top-5-learning-from-the-book-rework-4cp8</guid>
      <description>&lt;p&gt;In the world of business, where complexity often reigns supreme, “REWORK” by Jason Fried and David Heinemeier Hansson emerges as a refreshing departure from the norm. It’s a book that challenges conventional wisdom, advocating for simplicity, practicality, and unconventional thinking.&lt;/p&gt;

&lt;p&gt;“REWORK” isn’t your typical business manual filled with jargon and elaborate strategies. Instead, it’s a call to action—a guide for those who value getting things done without being bogged down by unnecessary complexity.&lt;/p&gt;

&lt;p&gt;In this blog post, I’ll share my top 5 takeaways from “REWORK” and how they’ve reshaped my approach to work and productivity. These lessons are not just theory; they’re actionable principles that can revolutionize your career and projects. Let’s explore the world of “REWORK” together.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Learning #1: Embrace Unconventional Thinking&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most impactful lessons from “REWORK” is the power of unconventional thinking. In a world where seeking advice and opinions is the norm, Fried and Heinemeier Hansson remind us that, more often than not, the world will offer convincing reasons why your innovative idea won’t work.&lt;/p&gt;

&lt;p&gt;They urge us to reflect on history and consider the countless groundbreaking inventions and innovations that were initially dismissed as impractical. From human flight to global communication, these achievements were once considered impossible.&lt;/p&gt;

&lt;p&gt;The key takeaway here is to not be discouraged by naysayers or conventional wisdom. Instead, embrace the idea that sometimes the most transformative ideas defy the status quo. “REWORK” encourages us to march to the beat of our own drum, to challenge the norm, and to explore possibilities beyond what the world may deem feasible.&lt;/p&gt;

&lt;p&gt;In the quest for innovation and progress, it’s essential to have the courage to pursue your vision, even when it appears unattainable to others. As “REWORK” reminds us, the world can be a discouraging place, but it’s those who dare to dream differently that often change it for the better.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Learning #2: Act on Your Ideas&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the realm of entrepreneurship and innovation, ideas are abundant. Yet, as “REWORK” passionately argues, the true value of an idea lies not in its conception, but in its execution.&lt;/p&gt;

&lt;p&gt;One of the resounding messages from the book is the importance of taking action. Rather than merely discussing and debating ideas, “REWORK” urges us to roll up our sleeves and start building. After all, a thousand brilliant ideas, left unimplemented, hold little value.&lt;/p&gt;

&lt;p&gt;The book emphasizes that implementation is where ideas truly come to life. It’s in the process of building, testing, and refining that ideas take shape and evolve into something meaningful. This hands-on approach aligns with the belief that action is the ultimate litmus test for any concept.&lt;/p&gt;

&lt;p&gt;So, whether you’re contemplating a business venture, a creative project, or a personal goal, “REWORK” encourages you not to overthink or overanalyze. Instead, dive headfirst into the act of creation. The sooner you start building, the sooner you can learn, iterate, and transform your ideas into tangible results.&lt;/p&gt;

&lt;p&gt;In a world where ideas are a dime a dozen, it’s those who act on them that leave an indelible mark. As “REWORK” reminds us, action, not ideation, is the catalyst for progress and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Learning #3: Prioritize Minimal Viable Products (MVPs)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a world where complexity often masquerades as progress, “REWORK” advocates for a fundamental principle: prioritize simplicity and focus on building a Minimal Viable Product (MVP).&lt;/p&gt;

&lt;p&gt;It’s natural to get caught up in the excitement of creating a sophisticated, feature-rich product or project. However, “REWORK” reminds us to pause and consider what is absolutely essential for a go-to-market offering.&lt;/p&gt;

&lt;p&gt;The authors emphasize that an MVP should contain only the core features required to meet your initial goals. This stripped-down version allows you to launch quickly and gather valuable feedback from users. In essence, it’s about getting your creation into the hands of users as soon as possible.&lt;/p&gt;

&lt;p&gt;By doing so, you can validate your concept, identify areas for improvement, and adapt to real-world feedback. This iterative approach to development aligns with the belief that perfection can be the enemy of progress.&lt;/p&gt;

&lt;p&gt;“REWORK” encourages us to resist the temptation to over-engineer and instead focus on delivering a product or project that addresses the immediate needs and pain points of your target audience. It’s the most direct path to market and the most effective way to refine your offering based on real-world usage.&lt;/p&gt;

&lt;p&gt;In a landscape where time-to-market can be a critical factor, “REWORK” underscores the importance of agility and the value of getting your creation out there, even in its simplest form.’&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Learning #4: Learning from Success, Not Just Failure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The conventional wisdom often tells us that success is born from a long string of failures. While “REWORK” acknowledges the value of learning from mistakes, it boldly challenges the notion that failure is a mandatory prerequisite for success.&lt;/p&gt;

&lt;p&gt;In the pursuit of our goals and ventures, it’s common to hear the adage, “If you fail a thousand times, you’ll discover a thousand ways that don’t work.” “REWORK,” however, invites us to reevaluate this perspective. It argues that focusing solely on failure can blind us to the path of success.&lt;/p&gt;

&lt;p&gt;The book contends that success stories, rather than being mere anomalies, provide valuable insights. By examining what works, we can actively seek out and replicate successful strategies. This proactive approach, often overlooked in the shadow of failure, can significantly expedite our journey to success.&lt;/p&gt;

&lt;p&gt;“REWORK” encourages us to study success stories, not just for inspiration, but as tangible roadmaps for our own endeavors. By understanding the elements and decisions that contributed to success, we can make informed choices and increase our chances of achieving our goals without the need for a trail of failures.&lt;/p&gt;

&lt;p&gt;The key takeaway here is that while failures may teach us resilience and perseverance, they are not the sole teachers of success. “REWORK” invites us to embrace the idea that learning from the achievements of others can be equally—if not more—valuable on our quest for greatness.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Learning #5: Build Products That Are “In-Home-Good”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the world of business, it’s easy to be captivated by products that are “in-store-good.” These are the items that dazzle us on store shelves, often sparking impulse purchases driven by their allure. Yet, as “REWORK” astutely points out, the initial excitement often fades, and these products end up collecting dust in a corner of our homes.&lt;/p&gt;

&lt;p&gt;“REWORK” imparts a critical lesson: successful products aren’t just those that look appealing in stores; they’re the ones that genuinely solve a problem or fulfill a need in our everyday lives. These are the products that are “in-home-good.”&lt;/p&gt;

&lt;p&gt;The authors emphasize that, as creators and entrepreneurs, our focus should be on crafting solutions that address specific customer problems. Instead of designing products that merely dazzle on the surface, we should strive to create offerings that make a meaningful difference in people’s lives.&lt;/p&gt;

&lt;p&gt;This concept aligns with the idea that lasting success comes from understanding and empathizing with the end-users’ needs. “REWORK” reminds us that flashy features and marketing hype may attract attention initially, but it’s the utility and value a product brings to its users that ensures its longevity.&lt;/p&gt;

&lt;p&gt;The takeaway here is clear: prioritize creating products that people genuinely need and want in their daily routines. By aligning your efforts with solving real-world problems, you’re not only more likely to achieve sustained success but also to make a lasting impact in the lives of your customers.&lt;/p&gt;

&lt;p&gt;In a world filled with fleeting trends and short-lived novelties, “REWORK” encourages us to be the creators of products that stand the test of time and truly enhance the human experience.&lt;/p&gt;

&lt;p&gt;By applying these principles, you can approach your work, projects, and entrepreneurial endeavors with a fresh perspective, embracing simplicity, innovation, and a focus on solving real-world problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link to “REWORK” on Amazon:&lt;/strong&gt; &lt;a href="https://amzn.eu/d/gKBIe2e"&gt;REWORK by Jason Fried and David Heinemeier Hansson&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/my-top-5-learning-from-the-book-rework/"&gt;My Top 5 learning from the Book “REWORK”&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>books</category>
    </item>
    <item>
      <title>Load .env Files in Node.js: The Old and New built-in Way</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Thu, 28 Sep 2023 15:16:08 +0000</pubDate>
      <link>https://dev.to/navinkprasad/load-env-files-in-nodejs-the-old-and-new-built-in-way-1ek1</link>
      <guid>https://dev.to/navinkprasad/load-env-files-in-nodejs-the-old-and-new-built-in-way-1ek1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello Friends, When developing Node.js applications that require configuration variables to be kept separate from the code, developers often create a &lt;code&gt;.env&lt;/code&gt; file to store these variables. Traditionally, the popular approach has been to use the &lt;code&gt;dotenv&lt;/code&gt; package to load these configuration variables. However, with the release of Node.js v20.6.0, the Node.js team has introduced built-in support for loading &lt;code&gt;.env&lt;/code&gt; files, eliminating the need for a third-party package.&lt;/p&gt;

&lt;p&gt;The dotenv is a great package which helped the developers to load configuration variables from .env file in many years but now the NodeJs team decided to support loading .env files as a build in feature and good news is this is released in Node.js v20.6.0.&lt;/p&gt;

&lt;p&gt;In this blog post we will see how we used to load .env files using dotenv package and then we will learn new way of loading .env file in NodeJs without installing any third party package.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Load .env Files with &lt;code&gt;dotenv&lt;/code&gt; (Traditional Method):
&lt;/h2&gt;

&lt;p&gt;Lets us create a Node.js Project.&lt;/p&gt;

&lt;p&gt;Create an folder and open that on VSCode as below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--245q8zaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--245q8zaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-41.png" alt="" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In terminal run npm init command as below, it give you couple of prompt, just press enter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vTD5oTQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vTD5oTQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-42.png" alt="" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the end a package.json file should be created for you.&lt;/p&gt;

&lt;p&gt;Create a new file index.js in the same folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yY7tiX3i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yY7tiX3i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-43.png" alt="" width="765" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create any .env file with some configuration for this demo I have created a .env file and named it “.env” at the root of the project. add a example cofiguration key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t-YPdWG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-46-1024x272.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t-YPdWG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-46-1024x272.png" alt="" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can keep actual configuration in this file in your real Node.js Projects.&lt;/p&gt;

&lt;p&gt;Now to explore old way of loading .env file, Lets us install the &lt;strong&gt;dotenv&lt;/strong&gt; package using below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;once done, you should see similar terminal output as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KQYajgMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KQYajgMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-45.png" alt="" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a index.js file just to see if we are able to read the configuration or not. The code is as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('dotenv').config()
console.log("Running...")
console.log("DATABASE_SERVER_NAME", process.env.DATABASE_SERVER_NAME)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the application and you should see the output in console as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ejLs-4o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ejLs-4o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-47.png" alt="" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see in above output that we are able to read the configuration value. This is how we used to load the env file till date.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Load .env Files in Node.js Without &lt;code&gt;dotenv&lt;/code&gt; (New Method):
&lt;/h2&gt;

&lt;p&gt;Now Lets us see the new way which is the loading the .env file in NodeJs without any third party package. Here the the steps.&lt;/p&gt;

&lt;p&gt;Make sure you are on Node.js v20.6.0 or latest. If not install the latest Node.js. If you manage the multiple Node.js version too using node version manager(nvm) , follow this post if you do not know how to install and use multiple nodeJs on same machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codelila.com/how-to-install-multiple-nodejs-versions-on-windows/"&gt;How to use nvm to install multiple nodeJS versions on windows? – CodeLila&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now switch to Node.js v20.6.0.&lt;/p&gt;

&lt;p&gt;remove the dotenv config line from the index.js as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log("Running...")
console.log("DATABASE_SERVER_NAME", process.env.DATABASE_SERVER_NAME)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run the application using below line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node --env-file .env index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should see the below output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sF9zHS1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sF9zHS1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-48.png" alt="" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see this output is same as when we loaded the .env file with dotenv packge.&lt;/p&gt;

&lt;p&gt;You can read more about this release here: &lt;a href="https://nodejs.org/en/blog/release/v20.6.0"&gt;https://nodejs.org/en/blog/release/v20.6.0&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Node.js v20.6.0 introduced a new built-in way to load &lt;code&gt;.env&lt;/code&gt; files, eliminating the need for the &lt;code&gt;dotenv&lt;/code&gt; package. This simplifies the process of managing configuration variables in Node.js applications. Developers can now choose between the traditional method and the new built-in approach based on their project’s requirements.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/load-env-files-nodejs-guide/"&gt;Load .env Files in Node.js: The Old and New built-in Way&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
    </item>
    <item>
      <title>Effortless Port Forwarding with VS Code: Accessing Local Services Online</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Wed, 20 Sep 2023 12:38:20 +0000</pubDate>
      <link>https://dev.to/navinkprasad/effortless-port-forwarding-with-vs-code-accessing-local-services-online-2476</link>
      <guid>https://dev.to/navinkprasad/effortless-port-forwarding-with-vs-code-accessing-local-services-online-2476</guid>
      <description>&lt;p&gt;Hello friends, suppose you are developing a Web Application or a API and you want to expose it to few peoples or may be your clients. You want them to try the application/API quickly, ( &lt;strong&gt;which is not hosted yet&lt;/strong&gt; ) and give their valuable feedback, so that you can make the necessary changes and then finally deploy it.&lt;/p&gt;

&lt;p&gt;It was tiresome task previously. Rather I would say, we hardly thought that this could also be a possible way to implement and test the APIs or Web Applications. As sharing the application from local development environment was not so easy.&lt;/p&gt;

&lt;p&gt;Now it has become simple and smooth by the use of VS code editor for development.&lt;/p&gt;

&lt;p&gt;Let us see how we can do it stepwise.&lt;/p&gt;

&lt;p&gt;Let us setup a sample react app. Go to the desired folder in command prompt and run this command to create a sample React app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app my-demo-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w0nm1KzP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w0nm1KzP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-22.png" alt="" width="742" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait for it to complete. You may get the similar window as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P6Q7pFNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-23-1024x606.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P6Q7pFNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-23-1024x606.png" alt="" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the app in VS code using the given command on same terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nnd3Cx-1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nnd3Cx-1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-24.png" alt="" width="777" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go to VS Code editor you just opened and then open its terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Be sure you are on VS Code version 1.82 or the latest one. You can check for it by going to the &lt;strong&gt;about&lt;/strong&gt; section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r6nT-yVy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-25-1024x686.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r6nT-yVy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-25-1024x686.png" alt="" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the application, then type the below command on the terminal and press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By now the demo app must be ready and running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NVyjkcio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-26-1024x734.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NVyjkcio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-26-1024x734.png" alt="" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;PORT FORWARDING:&lt;/strong&gt;  &lt;strong&gt;HOW TO SET PORT VISIBLITY TO PRIVATE.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;PORTS&lt;/strong&gt; tab on same panel where you run the above command. You will encounter the below options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IbcyMIoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IbcyMIoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-27.png" alt="" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you have to configure the port that you want to forward.&lt;/p&gt;

&lt;p&gt;Right now the demo app is running on port 3000, and you want that to be accessible to your clients over the internet. For that you need to specify port 3000 in port column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2zHsZrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-28-1024x243.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2zHsZrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-28-1024x243.png" alt="" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will ask you to signin to GitHub, as given below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HP4E_J5b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HP4E_J5b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-29.png" alt="" width="597" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on “ &lt;strong&gt;Allow”&lt;/strong&gt; and sign in on GitHub. After successful sign in, it will ask for permission to open the URI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y7V7rE3k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y7V7rE3k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-30.png" alt="" width="600" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Allow by clicking “ &lt;strong&gt;Open&lt;/strong&gt; “. You may get the notification as below while it is progressing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uzFq35ED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-31-1024x212.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uzFq35ED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-31-1024x212.png" alt="" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On completion, the port tab will have the entry for your port.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vWtOhhqq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-32-1024x122.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWtOhhqq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-32-1024x122.png" alt="" width="800" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default the visibility will be private and it will allow to access the forwarded address only if you signin in GitHub. This is one way to use the forwarded address.&lt;/p&gt;

&lt;p&gt;Let us copy the forwarded address and open it on broswer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agoEsqjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agoEsqjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-33.png" alt="" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will ask you to verify your identity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VwbCTkk2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-34-1024x608.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VwbCTkk2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-34-1024x608.png" alt="" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “ &lt;strong&gt;Authorize Dev Tunnels”&lt;/strong&gt; , and it will redirect you to the application. You might encounter somewhat similar warning window as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SfBR6uNK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-35-1024x688.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SfBR6uNK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-35-1024x688.png" alt="" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “ &lt;strong&gt;Continue”&lt;/strong&gt; as we trust the URI/Application we are trying to access. You will see the application running on forwarded addess.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oezhSiVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-36-1024x680.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oezhSiVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-36-1024x680.png" alt="" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can change the forwaded address to public, so that you are not asked for any GitHub authorizations. Let us expore that too.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;PORT FORWARDING: HOW TO SET PORT VISIBLITY TO PUBLIC.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Right click on the forwarded port entry and go to “ &lt;strong&gt;Port Visibility&lt;/strong&gt; “.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ttNnlQJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-37-1024x397.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ttNnlQJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-37-1024x397.png" alt="" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;make it “ &lt;strong&gt;Public&lt;/strong&gt; “&lt;/p&gt;

&lt;p&gt;Now, access the same forwarded address on browser. Here also, you will get some similar warning window as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dPieeh3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-38-1024x648.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dPieeh3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-38-1024x648.png" alt="" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;click “ &lt;strong&gt;Continue&lt;/strong&gt; “&lt;/p&gt;

&lt;p&gt;and you will see the app runnning on forwarded port without doing any GitHub authentication/authorization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oaHpwVjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-39-1024x586.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oaHpwVjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-39-1024x586.png" alt="" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also edit the port protocal. For this Right click on the port entry and go to “ &lt;strong&gt;Change Port Protocol&lt;/strong&gt; “, then select “ &lt;strong&gt;HTTPS&lt;/strong&gt; ” over there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l-jkrNFM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-40-1024x380.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l-jkrNFM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-40-1024x380.png" alt="" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can read more about port fowarding feature &lt;a href="https://code.visualstudio.com/docs/editor/port-forwarding"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this blog post, we explored how Visual Studio Code (VS Code) simplifies the process of sharing and testing web applications and APIs. We started by creating a sample React app, then used VS Code to manage and run it effortlessly. VS Code’s “PORTS” tab allowed us to expose our app over the internet, with the option for GitHub authentication or making it public. We also learned how to enhance security by switching to the “HTTPS” protocol. Ultimately, VS Code proves to be an invaluable tool for developers, streamlining collaboration and ensuring polished results in web development.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/vs-code-port-forwarding-access-local-services-online/"&gt;Effortless Port Forwarding with VS Code: Accessing Local Services Online&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>portforwarding</category>
    </item>
    <item>
      <title>Mastering API Versioning in ASP.NET Core WebAPI: 3 Proven Methods to implement it</title>
      <dc:creator>Navin Prasad</dc:creator>
      <pubDate>Fri, 15 Sep 2023 12:49:06 +0000</pubDate>
      <link>https://dev.to/navinkprasad/mastering-api-versioning-in-aspnet-core-webapi-3-proven-methods-to-implement-it-11h4</link>
      <guid>https://dev.to/navinkprasad/mastering-api-versioning-in-aspnet-core-webapi-3-proven-methods-to-implement-it-11h4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I started learning Asp.net WebAPIs few year back for a client project, I learned how to implement webAPI and how that can be exposed. There was a chapter in the book which talked about API versioning. I read that but I thought it might be for letter stage of application, or large applications only.&lt;/p&gt;

&lt;p&gt;But what I realized while doing actual API project development , The API versioning is as important as exposing the API for the client to consume. It gives your application the direction for the future enhancements without lots of breaking changes due to technical debts.&lt;/p&gt;

&lt;p&gt;You might have came across third party APIs like “/api/v1/Products” , where “v1” is actually API version1. So, here we are going to learn all about API versioning in this blog with actual implemetation in a sample project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to implement API Versioning
&lt;/h2&gt;

&lt;p&gt;We can implement Api vesioning basically in three ways :-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL based API Versioning&lt;/li&gt;
&lt;li&gt;Header based API Versioning&lt;/li&gt;
&lt;li&gt;Query Parameter based API Versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sample Project to implement API versioning.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Visual studio 2022 , go to File-&amp;gt;New-&amp;gt;Project, select ASP.NET Core Web API Project template and click on Next.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5AsrY9Qg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-1024x658.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5AsrY9Qg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-1024x658.png" alt="" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give a name to the project , for instance “api-versioning-example” and click on Next.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ihRn_Fg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-1-1024x674.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ihRn_Fg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-1-1024x674.png" alt="" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select “.Net 7.0 (Standard Term Support)” as a Framework and Click on Create.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i3Gjxidg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-2-1024x684.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3Gjxidg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-2-1024x684.png" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After successful creation, you would able to see a window somewhat like the below one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ORmgZMsp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-3-1024x541.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ORmgZMsp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-3-1024x541.png" alt="" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will add another assembly project to keep the API projects Models seperate. It is always a good practice to divide the code based on their logic and functions.&lt;/p&gt;

&lt;p&gt;Select the solution and then Right click then Add-&amp;gt;New Project and select the DLL category and then select the Class Library(.Net Framework) Project template from the List.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zGujCpU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-4-1024x329.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zGujCpU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-4-1024x329.png" alt="" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Next. You need to provide the name for the DLL project now. name it like “api-versioning-Models” and click on Create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--arjYV_6l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-5-1024x668.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--arjYV_6l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-5-1024x668.png" alt="" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new Project should be added to your solution now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LyFj1irj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LyFj1irj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-6.png" alt="" width="455" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delete the “Class1.cs” file and add the two folders names “Domains” and “DTOs” in it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2enTVZEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2enTVZEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-7.png" alt="" width="461" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Domains folder add a new Class name “Product” and update its code to have some sample properties as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

namespace api_example_Models.Domains
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }

        public double Price { get; set; }
    }
}

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

&lt;/div&gt;



&lt;p&gt;In DTOs folder add a new class name “ProductDTO” and update it as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

namespace api_example_Models.DTOs
{
    public class ProductDTO
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }
        public double Price { get; set; }
    }
}

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

&lt;/div&gt;



&lt;p&gt;The final structure should be as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aCzEf3vN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aCzEf3vN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-8.png" alt="" width="432" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now add a new DLL project in solution and name it “api-example-DataContext” , once Done, delete the “Class1.cs” file from it.&lt;/p&gt;

&lt;p&gt;Now Select the “api-example-DataContext” Project and add the “api-example-Models” project as reference in it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RULKcZ_L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-9-1024x231.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RULKcZ_L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-9-1024x231.png" alt="" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a new Class “Products” in “api-example-DataContext” and update its code to return a sample product list. In actual application this would be returned from some storage(databases).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Linq;
using api_example_Models;
using api_example_Models.Domains;

namespace api_example_DataContext
{
    public class Products
    {
        public List&amp;lt;Product&amp;gt; GetProducts()
        {
            // Sample Product List
            var products = new List&amp;lt;Product&amp;gt;();
            products.Add(new Product()
            {
                Id = 1,
                Name = "Product 1",
                Description = "Product 1 descrition",
                Category = "Fasion",
                Price = 250
            }
            );
            products.Add(new Product()
            {
                Id = 1,
                Name = "Product 2",
                Description = "Product 2 descrition",
                Category = "Electronics",
                Price = 150
            });

            return new List&amp;lt;Product&amp;gt;();
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EzMqwGwA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EzMqwGwA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-10.png" alt="" width="461" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now select the api project and add other two projects as reference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jsJbNvu3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-11-1024x220.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jsJbNvu3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-11-1024x220.png" alt="" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now select the “Controllers” and add a new API controller , name it “ProductController”. Now we will be creating a GET api which should returns all products, Update the ProductController with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using api_example_Models.DTOs;
using api_example_DataContext;

namespace api_versioning_example.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        [HttpGet]
        public ActionResult&amp;lt;List&amp;lt;ProductDTO&amp;gt;&amp;gt; GetAllProducts()
        {
            var productDTOs = new List&amp;lt;ProductDTO&amp;gt;();
            var products = new Products().GetProducts(); 
            if(products != null)
            {
                foreach (var product in products)
                {
                    productDTOs.Add(new ProductDTO()
                    {
                        Id = product.Id,
                        Name = product.Name,
                        Description = product.Description,
                        Price = product.Price,
                        Category = product.Category,
                    });
                }
            }
            return productDTOs;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;Out basic API is ready now. Lets test it once on browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WJX8N3Vs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-12-1024x181.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WJX8N3Vs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-12-1024x181.png" alt="" width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  URL based API Versioning
&lt;/h2&gt;

&lt;p&gt;Now Lets start implementing the URL based API Versioning .&lt;/p&gt;

&lt;p&gt;Right click on “api-versioning-example” project and then click on “manage Nuget package”. Search for “Microsoft.AspNetCore.Mvc.Versioning” package and install in your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EuDrDN96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-13-1024x269.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EuDrDN96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-13-1024x269.png" alt="" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once installed, you should see message as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CRHHSWIH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-14-1024x241.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CRHHSWIH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-14-1024x241.png" alt="" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now Open Program.cs file and enable api versioning by adding below line of code just after the “builder.Services.AddControllers();” line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddApiVersioning();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4EAPfxBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-15-1024x176.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4EAPfxBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-15-1024x176.png" alt="" width="800" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go we have to build two version of DTOs as the new DTO would going to return the resired changes in newer API version.&lt;/p&gt;

&lt;p&gt;Lets go to “api-example-DataModels” Project and create new folder under the DTOs folder, I have named it “V2”, next add a new class file named “ProductDTOV2”. Update it code with below code given. Let us suppose we need to rename few fields in new api version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

namespace api_example_Models.DTOs.V2
{
    public class ProductDTOV2
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public string LongDescription { get; set; }
        public string Category { get; set; }
        public double Price { get; set; }
    }
}

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

&lt;/div&gt;



&lt;p&gt;In above code I have update the Name to ProductName and Description to LongDescription.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OS8ItP72--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-17-1024x300.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OS8ItP72--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-17-1024x300.png" alt="" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next go to ProductController in Controllers folder and add a new HTTPGET method to return add Product with updated names. Here is the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        [HttpGet]
        public ActionResult&amp;lt;List&amp;lt;ProductDTOV2&amp;gt;&amp;gt; GetAllProductsV2()
        {
            var productDTOs = new List&amp;lt;ProductDTOV2&amp;gt;();
            var products = new Products().GetProducts();
            if (products != null)
            {
                foreach (var product in products)
                {
                    productDTOs.Add(new ProductDTOV2()
                    {
                        Id = product.Id,
                        ProductName = product.Name,
                        LongDescription = product.Description,
                        Price = product.Price,
                        Category = product.Category,
                    });
                }
            }
            return productDTOs;
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we want to serve this new GET method when someone type “/api/v2/Product” and return the previous Get method (GetAllProducts) response when someone type “/api/v1/Product”. Let us update the ProductController to achieve this.&lt;/p&gt;

&lt;p&gt;In Product Controller just above the class Name add below line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("2.0")]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add below line just above the [HttpGET] for the “GetAllProducts” method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[MapToApiVersion("1.0")]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add below line above the [HttpGet] for the “GetAllProductsV2” method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[MapToApiVersion("2.0")]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how the final ProductController looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using api_example_Models.DTOs;
using api_example_DataContext;
using api_example_Models.DTOs.V2;

namespace api_versioning_example.Controllers
{
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("2.0")]
    public class ProductController : ControllerBase
    {
        [MapToApiVersion("1.0")]
        [HttpGet]
        public ActionResult&amp;lt;List&amp;lt;ProductDTO&amp;gt;&amp;gt; GetAllProducts()
        {
            var productDTOs = new List&amp;lt;ProductDTO&amp;gt;();
            var products = new Products().GetProducts(); 
            if(products != null)
            {
                foreach (var product in products)
                {
                    productDTOs.Add(new ProductDTO()
                    {
                        Id = product.Id,
                        Name = product.Name,
                        Description = product.Description,
                        Price = product.Price,
                        Category = product.Category,
                    });
                }
            }
            return productDTOs;
        }

        [MapToApiVersion("2.0")]
        [HttpGet]
        public ActionResult&amp;lt;List&amp;lt;ProductDTOV2&amp;gt;&amp;gt; GetAllProductsV2()
        {
            var productDTOs = new List&amp;lt;ProductDTOV2&amp;gt;();
            var products = new Products().GetProducts();
            if (products != null)
            {
                foreach (var product in products)
                {
                    productDTOs.Add(new ProductDTOV2()
                    {
                        Id = product.Id,
                        ProductName = product.Name,
                        LongDescription = product.Description,
                        Price = product.Price,
                        Category = product.Category,
                    });
                }
            }
            return productDTOs;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;Now run the application you will see swagger is giving some error, which we will fix later.&lt;/p&gt;

&lt;p&gt;Now go to the browser and the the Product url with V1(&lt;a href="http://localhost:5062/api/v1/Product"&gt;http://localhost:5062/api/v1/Product&lt;/a&gt;) as below. you should have response as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H8UB9kJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-18-1024x231.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H8UB9kJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-18-1024x231.png" alt="" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now type the new V2 Api for Product “&lt;a href="http://localhost:5062/api/v2/Product%E2%80%9D"&gt;http://localhost:5062/api/v2/Product”&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TkIINMGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-19-1024x213.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TkIINMGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-19-1024x213.png" alt="" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you notice the two outputs, you would fine the V1 is returning the same response but V2 is returning the updated response. but if you type the old url(&lt;a href="http://localhost:5062/api/Product"&gt;http://localhost:5062/api/Product&lt;/a&gt;) without version which was published then you may get error.&lt;/p&gt;

&lt;p&gt;This is how you can add support for api versioning in you asp.net WebAPI project.&lt;/p&gt;

&lt;p&gt;We have seen how we can add support for API versioning in route which is more popular and obvious way but there are other ways as well which can be also be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Header based API Versioning
&lt;/h2&gt;

&lt;p&gt;To implement header based versioning we need to make following changes in application.&lt;/p&gt;

&lt;p&gt;Replace the “builder.Services.AddApiVersioning()” line in program.cs file with below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddApiVersioning(options =&amp;gt;
{
    options.ApiVersionReader = new HeaderApiVersionReader("api-version");
    options.ReportApiVersions = true;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the “[Route(“api/v{version:apiVersion}/[controller]”)]” in ProductController file with “[Route(“api/[controller]”)]”.&lt;/p&gt;

&lt;p&gt;Now run the application, you need to use some rest client like postman to pass the header information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---daQylvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-20-1024x719.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---daQylvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-20-1024x719.png" alt="Api Versioning" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can try changing the “api-version” header to 2.0, you should be getting the 2.0 products output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Parameter based API Versioning
&lt;/h2&gt;

&lt;p&gt;Now let us take a look on how to implement Query Parameter based API Versioning.&lt;/p&gt;

&lt;p&gt;Let us go to program.cs file and update the below line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddApiVersioning(options =&amp;gt;
{
    options.ApiVersionReader = new HeaderApiVersionReader("api-version");
    options.ReportApiVersions = true;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the “HeaderApiVersionReader” to “QueryStringApiVersionReader”, the updated code should be looks like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddApiVersioning(options =&amp;gt;
{
    options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
    options.ReportApiVersions = true;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;browse the url with api-version as parameter. You should have similar output as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gSN76KgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-21-1024x628.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gSN76KgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codelila.com/wp-content/uploads/2023/09/image-21-1024x628.png" alt="" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how you can implement the API versioning in asp.net core API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this comprehensive guide, we dive deep into the world of API versioning within ASP.NET Core WebAPI. You’ll discover three battle-tested methods for implementing API versioning effectively, ensuring seamless compatibility across your applications. Whether you’re an experienced developer or just starting your journey, this post provides invaluable insights to help you manage and optimize your APIs with confidence. Explore the latest techniques and best practices to stay ahead in the ever-evolving landscape of ASP.NET Core WebAPI.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://codelila.com/mastering-api-versioning-aspnet-core-webapi-3-methods-seamless-compatibility/"&gt;Mastering API Versioning in ASP.NET Core WebAPI: 3 Proven Methods to implement it&lt;/a&gt; appeared first on &lt;a href="https://codelila.com"&gt;CodeLila&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webapi</category>
      <category>net</category>
      <category>net7</category>
      <category>apiversioning</category>
    </item>
  </channel>
</rss>
