<?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: Anil Kumar</title>
    <description>The latest articles on DEV Community by Anil Kumar (@im_lakhlan).</description>
    <link>https://dev.to/im_lakhlan</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%2F1808124%2F9fe98ccb-dbb8-44ed-8fb6-e6bf1efb0f59.png</url>
      <title>DEV Community: Anil Kumar</title>
      <link>https://dev.to/im_lakhlan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/im_lakhlan"/>
    <language>en</language>
    <item>
      <title>How to Build a GraphQL API from Scratch in Node.js</title>
      <dc:creator>Anil Kumar</dc:creator>
      <pubDate>Sun, 02 Feb 2025 09:44:40 +0000</pubDate>
      <link>https://dev.to/im_lakhlan/how-to-build-a-graphql-api-from-scratch-in-nodejs-hlo</link>
      <guid>https://dev.to/im_lakhlan/how-to-build-a-graphql-api-from-scratch-in-nodejs-hlo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;GraphQL has revolutionised API development by offering a flexible and efficient way to query data. Unlike REST APIs, where you often fetch unnecessary data or make multiple requests, GraphQL allows clients to request exactly what they need in a single request.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll build a GraphQL API from scratch using Node.js and Apollo Server. Our API will handle users and posts, providing a structured example of queries and mutations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’ll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a Node.js GraphQL server with Apollo Server&lt;/li&gt;
&lt;li&gt;Defining a GraphQL schema (types, queries, and mutations)&lt;/li&gt;
&lt;li&gt;Creating resolvers to handle requests&lt;/li&gt;
&lt;li&gt;Connecting to MongoDB using Mongoose&lt;/li&gt;
&lt;li&gt;Implementing JWT authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is Apollo and why are we using it here? Apollo is a popular GraphQL server and client library. We use Apollo Server in Node.js to handle GraphQL queries, mutations, and subscriptions efficiently, providing features like schema stitching, caching, and middleware integration.&lt;/p&gt;

&lt;p&gt;Let’s get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Install Node.js &amp;amp; Initialise the Project&lt;br&gt;
Ensure you have Node.js installed. Then, create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir graphql-blog-api &amp;amp;&amp;amp; cd graphql-blog-api
npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Required Dependencies&lt;br&gt;
We’ll use Apollo Server (for GraphQL), Express (for handling requests), and Mongoose (for MongoDB).&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 express apollo-server-express graphql mongoose jsonwebtoken bcryptjs dotenv cors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Why are we installing jsonwebtoken, bcryptjs, and cors?&lt;br&gt;
jsonwebtoken — Used for authentication via JWT tokens.&lt;br&gt;
bcryptjs — Used for securely hashing and comparing passwords.&lt;br&gt;
cors — Enables Cross-Origin Resource Sharing (CORS), allowing the API to be accessed from different domains.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For development, install Nodemon:&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 --save-dev nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update package.json to enable auto-reloading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
 "dev": "nodemon index.js"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2️⃣ Defining the GraphQL Schema
&lt;/h2&gt;

&lt;p&gt;GraphQL relies on a schema to define types and queries. Let’s create a schema.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { gql } = require("apollo-server-express");
// type defines a GraphQL object structure, and typedefs (short for type definitions) collectively define the GraphQL schema, including queries and mutations.
const typeDefs = gql`
    type User {
        id: ID!
        name: String!
        email: String!
        password: String!
    }
    type Post {
        id: ID!
        title: String!
        content: String!
        authorId: ID!
        author: User
    }
    type Query {
        users: [User]
        posts: [Post]
    }
    type Mutation {
        register(name: String!, email: String!, password: String!): User
        login(email: String!, password: String!): String
        createPost(title: String!, content: String!): Post
    }
`;
module.exports = typeDefs;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;What is gql?&lt;br&gt;
gql (GraphQL Tag) is a template literal function from Apollo that parses GraphQL schema definitions into an AST (Abstract Syntax Tree).&lt;br&gt;
What does ! mean in types?&lt;br&gt;
The ! denotes a non-nullable field, meaning the field must have a value and cannot be null.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3️⃣ Setting Up Resolvers
&lt;/h2&gt;

&lt;p&gt;Resolvers define how GraphQL responds to queries and mutations. Create resolvers.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const User = require("../models/User");
const Post = require("../models/Post");

const resolvers = {
  Query: {
    users: async () =&amp;gt; await User.find(),
    posts: async () =&amp;gt; await Post.find().populate("author"),
  },

  Mutation: {
    register: async (_, { name, email, password }) =&amp;gt; {
      const hashedPassword = await bcrypt.hash(password, 10);
      return await User.create({ name, email, password: hashedPassword });
    },

    login: async (_, { email, password }) =&amp;gt; {
      const user = await User.findOne({ email });
      if (!user || !(await bcrypt.compare(password, user.password))) {
        throw new Error("Invalid credentials");
      }
      return jwt.sign({ ...user.toObject() }, process.env.JWT_SECRET, { expiresIn: "1h" });
    },
    createPost: async (_, { title, content }, { user }) =&amp;gt; {
      if (!user) throw new Error("Authentication required");
      const post = Post({ title, content, authorId: user._id });
      await post.save();
      return await Post.findById(post._id).populate('author');
    },
  },
};
module.exports = resolvers;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4️⃣ Connecting to MongoDB
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file to store the MongoDB URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGO_URI=mongodb://localhost:27017/graphql_blog
JWT_SECRET="secretKey"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create models/User.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
    name: String,
    email: String,
    password: String,
});
module.exports = mongoose.model("User", userSchema);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And models/Post.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");
const postSchema = new mongoose.Schema({
    title: String,
    content: String,
    authorId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
});

postSchema.virtual('author', {
    localField: 'authorId',
    foreignField: '_id',
    ref: 'User',
    justOne: true
})

module.exports = mongoose.model("Post", postSchema);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5️⃣ Running &amp;amp; Testing the API
&lt;/h2&gt;

&lt;p&gt;Create index.js to set up Apollo Server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
require('dotenv').config();
const { ApolloServer } = require('apollo-server-express');
const mongoose = require('mongoose');
const typeDefs = require("./src/graphql/schema");
const resolvers = require("./src/graphql/resolvers");

const app = express();

mongoose.connect(process.env.MONGO_URI)
  .then(() =&amp;gt; console.log('connected to mongodb'))
  .catch((err) =&amp;gt; console.log('Not able to connect to mongodb', err));

const jwt = require('jsonwebtoken');

const context = ({ req }) =&amp;gt; {
  const authHeader = req.headers.authorization || '';
  const token = authHeader.split(' ')[1]; // Extract token from "Bearer &amp;lt;token&amp;gt;"

  if (token) {
    try {
      const user = jwt.verify(token, process.env.JWT_SECRET); // Decode user
      return { user }; // Attach user to context
    } catch (err) {
      console.log('Invalid Token');
    }
  }
  return {}; // No user attached if token is missing/invalid
};


const server = new ApolloServer({
  typeDefs,
  resolvers,
  context
});

async function startServer() {
  await server.start();
  server.applyMiddleware({ app });

  // Start Express Server
  app.listen(4000, () =&amp;gt; {
    console.log(`Server running at http://localhost:4000${server.graphqlPath}`);
  });
}

startServer();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the API:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Test queries in GraphQL Playground at &lt;code&gt;http://localhost:4000/graphql&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;🎉 You’ve built a GraphQL API from scratch using Node.js, Apollo Server, and MongoDB. You learned:&lt;br&gt;
✅ How to define a GraphQL schema&lt;br&gt;
✅ How to set up queries and mutations&lt;br&gt;
✅ How to connect to MongoDB&lt;br&gt;
✅ How to authenticate users&lt;/p&gt;

&lt;p&gt;Next Steps: Add subscriptions for real-time updates or build a React frontend!&lt;/p&gt;

&lt;p&gt;🚀 What would you like to learn next? Drop a comment below!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hot Cache and Cold Cache: A UI Perspective</title>
      <dc:creator>Anil Kumar</dc:creator>
      <pubDate>Mon, 27 Jan 2025 08:57:10 +0000</pubDate>
      <link>https://dev.to/im_lakhlan/hot-cache-and-cold-cache-a-ui-perspective-4477</link>
      <guid>https://dev.to/im_lakhlan/hot-cache-and-cold-cache-a-ui-perspective-4477</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe7hprmnj96xgnxa9aat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe7hprmnj96xgnxa9aat.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In modern web development, speed and efficiency play a significant role in delivering a seamless user experience. Caching is one of the most powerful tools to achieve this. In this blog, we’ll explore the concepts of hot caching and cold caching from a UI perspective, explaining how they impact performance and user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Caching?
&lt;/h2&gt;

&lt;p&gt;Caching involves storing data temporarily in a location that allows for quick access, reducing the need for repetitive network requests. In a UI context, caching is often used to load data faster, making the app feel responsive and user-friendly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hot Caching vs. Cold Caching
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hot Caching&lt;/strong&gt;:&lt;br&gt;
Refers to data that is frequently accessed and is already available in the cache.&lt;br&gt;
Provides faster response times as the data doesn’t need to be fetched from the server.&lt;br&gt;
Ideal for frequently used data like user preferences or dashboards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cold Caching:&lt;/strong&gt;&lt;br&gt;
Refers to data that is not available in the cache and requires fetching from the server or database.&lt;br&gt;
Slower response times are expected because the data retrieval process involves additional steps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Impact on UI/UX:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Hot Caching ensures a snappier UI, as data is readily available. This results in improved user satisfaction.&lt;/li&gt;
&lt;li&gt;Cold Caching, while slower, is necessary for fetching data initially or for rarely accessed information.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Best Practices for UI Caching:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Set Expiry Times:
Use time-to-live (TTL) to ensure cache doesn’t store stale data.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const cacheWithTTL = new Map();
const TTL = 60000; // 1 minute

function setCache(key, value) {
  cacheWithTTL.set(key, { value, expiry: Date.now() + TTL });
}

function getCache(key) {
  const cached = cacheWithTTL.get(key);
  if (cached &amp;amp;&amp;amp; cached.expiry &amp;gt; Date.now()) {
    return cached.value;
  }
  cacheWithTTL.delete(key);
  return null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Preload Data:&lt;br&gt;
Pre-fetch critical data when the app starts or when the user logs in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invalidate Cache Strategically:&lt;br&gt;
Ensure data consistency by invalidating and refreshing outdated cache entries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Local Storage for Persistence:&lt;br&gt;
For less critical but reusable data, local storage can act as a cache.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Hot and cold caching are essential concepts in optimising UI performance. By effectively using caching strategies, you can deliver faster applications, reduce server load, and enhance user experience. Always balance between performance and consistency to provide the best results.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>caching</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
