<?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: Bibek Dhami</title>
    <description>The latest articles on DEV Community by Bibek Dhami (@bvekv1).</description>
    <link>https://dev.to/bvekv1</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%2F319411%2Fd7318e05-9796-41c6-8da4-81956010674f.jpg</url>
      <title>DEV Community: Bibek Dhami</title>
      <link>https://dev.to/bvekv1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bvekv1"/>
    <language>en</language>
    <item>
      <title>User Authentication In Nodejs</title>
      <dc:creator>Bibek Dhami</dc:creator>
      <pubDate>Thu, 05 Aug 2021 16:34:23 +0000</pubDate>
      <link>https://dev.to/bvekv1/user-authentication-in-nodejs-3c4l</link>
      <guid>https://dev.to/bvekv1/user-authentication-in-nodejs-3c4l</guid>
      <description>&lt;p&gt;Login and managing authentication is one of the keys to every application for authentication and security. JsonWebToken allows verifying a user in a secure away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Package&lt;/li&gt;
&lt;li&gt; Register User&lt;/li&gt;
&lt;li&gt;Login User and Generate JsonWebToken&lt;/li&gt;
&lt;li&gt;Verifying Token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install-Package&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 bcrypt
npm install jsonwebtoken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;bcrypt will be used to hash the password oneway.&lt;br&gt;
JSON Web Token will be used to create tokens and to verify the created token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Register User&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;module.exports.register = async(req,res)=&amp;gt;{
 let password = req.body.password;
let saltRandom = Math.floor(Math.random()*10)
let salt = bcrypt.genSaltSync(saltRandom)
bcrypt.hash(password,salt,function(err,hash){
if(err){
 res.json({message:"Error while hashing"})
}
let insertObject ={};
insertObject.name = req.body.name;
insertObject.email = req.body.email;
insertObject.salt = salt;
insertObject.password =hash;

knex("tbl_user").insert(insertObject).then((doc)=&amp;gt;{
 res.json({status:"success",message:"success"})
}).catch((err)=&amp;gt;{
 res.json({status:"erorr",message:"error"})
})
})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The random salt number is generated using math floor and salt is bcrypted and bcrypt.hash function is used to hash the password. Bcrypt hash the password in one way, hash value can`t be reversed to the original value but can be compared. To prevent from a rainbow table we are using random salt values to make it more difficult for hackers to get the hash value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:  Login User&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select the password hash and compare it with the password user field while login. And if the has value match general token using JSON web token. Additional Information can be sent in payLoad such as userId. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;JsonWeb Token contains 3 parts&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;=&amp;gt; &lt;em&gt;Header&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;it contains an algorithm used to sign in the token and token type.&lt;/p&gt;

&lt;p&gt;=&amp;gt;&lt;em&gt;PayLoad&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the payLoad part of the token additional data can be added as needed for further use.&lt;/p&gt;

&lt;p&gt;=&amp;gt;&lt;em&gt;Signature&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;encoded header, encoded payload, encoded secret key given by user and algorithm is used to sign the token.&lt;/p&gt;

&lt;p&gt;Using all three structures it generates a base64-URL string separated by dots.&lt;br&gt;
This is what jwt token look like when decoded:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--48EvEYoG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628180244301/Di_iPrzVk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--48EvEYoG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628180244301/Di_iPrzVk.png" alt="decoded.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
module.exports.login= async(req,res)=&amp;gt;{&lt;br&gt;
    let email = req.body.email;&lt;br&gt;
    let password = req.body.password;&lt;br&gt;
    await knex("tbl_user").select('*').where('email',email).then((doc)=&amp;gt;{&lt;br&gt;
        bcrypt.compare(password,doc[0].password).then((isMatch)=&amp;gt;{&lt;br&gt;
            if(!isMatch){&lt;br&gt;
                let err = new Error("Email Id or password does not exist");&lt;br&gt;
                err.status =404;&lt;br&gt;
                return next(err);&lt;br&gt;
            }else&lt;br&gt;
            {&lt;br&gt;
                let payLoad = {&lt;br&gt;
                        userId:doc[0].userId,&lt;br&gt;
                        email:doc[0].email&lt;br&gt;
                }&lt;br&gt;
                jwt.sign(payLoad,"hashNode",(err,jwtToken) =&amp;gt; {&lt;br&gt;
                    res.json({&lt;br&gt;
                        status:"200",&lt;br&gt;
                         token:jwtToken&lt;br&gt;
                    })&lt;br&gt;
                })&lt;br&gt;
        }&lt;br&gt;
        })&lt;br&gt;
    }).catch((err)=&amp;gt;{&lt;br&gt;
            res.json({status:"error",message:"error"})&lt;br&gt;
    })&lt;/p&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 5: Verifying Token *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spilt the  to seprate Bearere form token. And verify token with JSON web token verify and with the secret key used to create token and if the token match the call the next(); &lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
let jwt = require('jsonwebtoken')&lt;/p&gt;

&lt;p&gt;module.exports.verifyToken = async(req,res,next)=&amp;gt;{&lt;br&gt;
    if(req.headers.authorization == undefined){&lt;br&gt;
        res.json({status:401,message:"Unauthorized"})&lt;br&gt;
    }&lt;br&gt;
    const token =req.headers.authorization.split(" ")&lt;br&gt;
    jwt.verify(token[1],"hashNode",function(err,result){&lt;br&gt;
        if(!result){&lt;br&gt;
            let err = new Error("Token misMatch")&lt;br&gt;
            err.status =401;&lt;br&gt;
            return next(err)&lt;br&gt;
        }else{&lt;br&gt;
            req.userId = result.userId;&lt;br&gt;
            req.email = result.email;&lt;br&gt;
            next();&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
&lt;code&gt;`&lt;br&gt;
 Create an API that only users whose token is verified can access. Include above middleware in routes.&lt;br&gt;
`&lt;/code&gt;&lt;br&gt;
module.exports.viewDetails = async(req,res) =&amp;gt; {&lt;br&gt;
    let userId = req.userId&lt;br&gt;
    await knex('tbl_user').select('*').where('userId',userId).then((doc)=&amp;gt;{&lt;br&gt;
        res.json({status:"success",message:doc})&lt;br&gt;
    }).catch((err)=&amp;gt;{&lt;br&gt;
        res.json({status:"err",message:"err"})&lt;/p&gt;

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

&lt;/div&gt;

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

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Routes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
router.post('/registerUser',register)&lt;br&gt;
router.post('/loginUser',login)&lt;/p&gt;

&lt;p&gt;router.get('/detail',verifyToken,viewDetails)&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Bvekv1/auth.git"&gt;SourceCode&lt;/a&gt; &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>File Upload With Multer</title>
      <dc:creator>Bibek Dhami</dc:creator>
      <pubDate>Thu, 05 Aug 2021 06:41:26 +0000</pubDate>
      <link>https://dev.to/bvekv1/file-upload-with-multer-4fpm</link>
      <guid>https://dev.to/bvekv1/file-upload-with-multer-4fpm</guid>
      <description>&lt;p&gt;Multer is a library for handling file upload with form/multipart-formdata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing Package&lt;/li&gt;
&lt;li&gt;Multer fileUpload and file type validation&lt;/li&gt;
&lt;li&gt;Initialize upload variable&lt;/li&gt;
&lt;li&gt;Insert image path in database&lt;/li&gt;
&lt;li&gt;Retrieve Uploaded Image&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Installing Package&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 multer
npm install path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;require both install packages at top of your code 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 multer = require('multer')
const path = require('path')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;2. Multer File Upload and file type validation *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;let's create a function which will store image.&lt;br&gt;
multer disk storage stores the file in the disk. multer will remove the file extension so that we can add the file extension with file.orginalname. &lt;/p&gt;

&lt;p&gt;Date.now() to give a unique name for each file. &lt;/p&gt;

&lt;p&gt;file.fieldname is a value that we specify in our form value.&lt;/p&gt;

&lt;p&gt;Note: If file.orginalname is not specified multer will assign a random file value for each file without extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const storage = multer.diskStorage({
     Destination:"upload/profile",
     Filename(req,fiel,cb)=&amp;gt;{
     cb(null,file.fieldname+"-"+Date.now()+file.originalname)
}
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specify the directory in which you want to store your files. No need to manually create your directory manually multer will take care of that for you.&lt;/p&gt;

&lt;p&gt;now let's add some file validation so that we can restrict users to only upload the filetype we defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fileFilter =(req,file,callback)=&amp;gt;{
let ext = apth.extname(file.originalname)
if(ext !=='png' &amp;amp;&amp;amp; ext !=='jpg' &amp;amp;&amp;amp; ext !=='jpeg'){
return callback(new Error('Only png, ext and jpeg fileType are allowed))
}
Callback(null,true)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Initialize Upload variable&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;let upload = multer({
storage:storage,
fileFilter:fileFilter
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For file upload &lt;/p&gt;

&lt;p&gt;"module.exports.imageName = upload.single("image")"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Insert ImagePath in DataBase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's insert Image Path and Image Name in the Database. We will use the above multer upload function as middleware for our function.  Multer provides an API through which we can retrieve the details of the file we have uploaded. Some of them are;&lt;br&gt;
file. filename will give us upload filename, mimetype will give us file extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports.profilePic = async(req,res)=&amp;gt;{
    let  insertObject ={};
    console.log(req.file)    
     insertObject.imageName = req.file.filename;
    insertObject.type = req.file.mimetype;
    insertObject.path = req.file.path
    insertObject.personId = req.params.personId;
     console.log("this is inside function",insertObject)
    await knex("tbl_profile").insert(insertObject).then((doc)=&amp;gt;{
        res.json({status:"success",message:"success"});
    }).catch((err)=&amp;gt;{
        console.log("THis is err",err)
        res.json({status:"error",message:"error"})
    })
}

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

&lt;/div&gt;



&lt;p&gt;create a router for inserting an image and use the image name function as middleware&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.post("/profile/:personId",imageName,profilePic)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;test image upload in postman&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628140302730%2FintWdg-IY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628140302730%2FintWdg-IY.png" alt="postManUpload.PNG"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;5. Reterive Image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the image has been added now let's retrieve the image by person Id.&lt;br&gt;
For that, we need to first select the image path for a given personId and then join it with a path to retrieve the image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports.pic = async(req,res)=&amp;gt;{
    const personId = req.params.personId;
    await knex("tbl_profile").select('path').where('personId',personId).then((doc)=&amp;gt;{
  let filePath = doc[0]
  let  imageUrl = filePath.path
  const dirname = path.resolve();
  const fileUrl = path.join(dirname,imageUrl);
        res.sendFile(fileUrl)
    }).catch((err)=&amp;gt;{
        console.log("This is an error",err)
        res.json({status:"error",message:"error reterving messsage"})
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.get("/profile/:personId",pic)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Preview Image Using Postman *&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628140331786%2FsezeQnc9J.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628140331786%2FsezeQnc9J.png" alt="reteriveImageUpload.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Bvekv1/knexCrud.git" rel="noopener noreferrer"&gt;SourceCode&lt;/a&gt; &lt;/p&gt;

</description>
      <category>node</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Unit testing in Nodejs Using Mocha</title>
      <dc:creator>Bibek Dhami</dc:creator>
      <pubDate>Tue, 03 Aug 2021 17:41:47 +0000</pubDate>
      <link>https://dev.to/bvekv1/unit-testing-in-nodejs-using-mocha-3ci8</link>
      <guid>https://dev.to/bvekv1/unit-testing-in-nodejs-using-mocha-3ci8</guid>
      <description>&lt;p&gt;To do unit testing in node we will be using mocha for running test cases and chai for BBD styles test cases.&lt;/p&gt;

&lt;p&gt;STEP 1:  &lt;strong&gt;Install Dependency&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 mocha
npm install chai
npm install chai-http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;STEP 2: &lt;strong&gt;Initialize test File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting Ready Test File&lt;br&gt;
require chai, chai-http and require file which starts your server&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ht3cfLnh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007010796/WRGlQUr6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ht3cfLnh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007010796/WRGlQUr6g.png" alt="setupTest.png"&gt;&lt;/a&gt;&lt;br&gt;
add mocha test in scripts in package.json to run test cases&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O6vsHX5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007552589/NQS97rOQs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O6vsHX5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007552589/NQS97rOQs.png" alt="script.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 3: &lt;strong&gt;Writing Test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As to be able to run only one test case at a time we can create an object with a unique key and assigning values true and false and we can use those object values to allow the test case to run only when the respective object key value to true by checking with if condition.Note if condition by default check for true no need to specify like this (test case.addObject == true).  We can define our test content type with .set to form-url encoded or application/JSON as required. Here Application/JSON will be used&lt;br&gt;
Creating Object with unique key and value. As our code to be tested is an async function we need to  set the parameter of &lt;em&gt;it block&lt;/em&gt; function to &lt;em&gt;done&lt;/em&gt; so that when mocha sees that our it block has a test case&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P1MJs_S8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007773127/nLV8gxVZc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P1MJs_S8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007773127/nLV8gxVZc.png" alt="creatingObject.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;test for add person&lt;br&gt;
As the function we are testing is an async function we need to specify done in our test case&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--92zcTuDU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007996677/_InWu9uP5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--92zcTuDU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628007996677/_InWu9uP5.png" alt="addPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
Patch(Update) Person&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zl-bJhEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008081310/4eRV-VrUv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zl-bJhEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008081310/4eRV-VrUv.png" alt="patchPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
for Get Person&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4hQt96eC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008152037/FD_S1vixB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4hQt96eC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008152037/FD_S1vixB.png" alt="getPerson.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can group the test case in a single function to make it more organize and distinguish from other unrelated test cases like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4W9VA7VC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008276118/Ww5mJcSkc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4W9VA7VC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008276118/Ww5mJcSkc.png" alt="singleFunctionPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
 add Favourite and get Favourite&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LQUiC72i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008543871/5xOEY_5Yy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LQUiC72i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628008543871/5xOEY_5Yy.png" alt="FavouriteAll.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 4: *&lt;em&gt;Running Test&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Now run the test case&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/Bvekv1/knexCrud.git"&gt;SourceCode&lt;/a&gt; &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Crud In NodeJs</title>
      <dc:creator>Bibek Dhami</dc:creator>
      <pubDate>Tue, 03 Aug 2021 17:33:26 +0000</pubDate>
      <link>https://dev.to/bvekv1/crud-with-knexjs-2dgg</link>
      <guid>https://dev.to/bvekv1/crud-with-knexjs-2dgg</guid>
      <description>&lt;h2&gt;
  
  
  Mysql With Knexjs In Node
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this section, we will learn how to set up and perform crud with knex.js in nodejs and I will be using &lt;br&gt;
Postman to test routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nVabQAZf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627725363328/VonzSRHNY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nVabQAZf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627725363328/VonzSRHNY.png" alt="directorytree.PNG"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;STEP&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1- Getting ready express framework&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 express
npm install body-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create an app.js file &lt;br&gt;
As we will be keeping our route in a separate directory import the directory with a file using the app. use(require("./routes/router")). In app.js file will only start the express server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iI7p59OE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627720727522/MfZpFXpKv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iI7p59OE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627720727522/MfZpFXpKv.png" alt="app.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in the router.js file set body-parser-urlencoded({extended: true}) uses express.json() to parse the JSON data which we will be sending through postman.&lt;/p&gt;

&lt;p&gt;Define all your routes here and import related functions in respective routes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4mSebE99--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627720798578/XosU3MCS2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4mSebE99--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627720798578/XosU3MCS2.png" alt="router.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;2- Installation&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 knex

 npm install mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3-Initialize Knex&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 knex init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4- Creating Migration 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;knex migrate: make tbl_person
knex migrate: make tbl_favourite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define Schema in the migration file. Migration file requires two functions up and down. Up function is run when creating a table in the database whereas the down function is run when rolling back migration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--urItSyYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718243836/wneKjHxSE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--urItSyYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718243836/wneKjHxSE.png" alt="tbl_person.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8r1tLyJq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718276357/eKjakWbfR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8r1tLyJq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718276357/eKjakWbfR.png" alt="tbl_fav.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5-Writing knex Query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Insert Person&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For inserting, I will be using the async arrow function. Store all the request body in an object along with the key that matches the field of the respective table and pass the object in knex query. Which knex will map it into raw SQL query under the hood.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zlsPsx2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718630860/hE8qz5sDE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zlsPsx2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718630860/hE8qz5sDE.png" alt="addPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
Testing insert api with postman&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fXQgIzQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719235573/GSSeMHMtL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fXQgIzQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719235573/GSSeMHMtL.png" alt="postPerson.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*Patch Person *&lt;/p&gt;

&lt;p&gt;For updating store the body data into object and params in a variable. To pass it into knex query as:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UbuWdT_M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718687894/wiwvkxACK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UbuWdT_M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718687894/wiwvkxACK.png" alt="patchPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
Testing Patch API&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sqso47r9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719283369/7ffBY8XhU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sqso47r9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719283369/7ffBY8XhU.png" alt="patchPerson.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*Get Person *&lt;/p&gt;

&lt;p&gt;For selecting person knex orm query is as:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G7s2JV4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718721273/dwit8zvF_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G7s2JV4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718721273/dwit8zvF_.png" alt="getPerson.png"&gt;&lt;/a&gt;&lt;br&gt;
testing get person API&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--myRpum2M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719721493/V8zA4Rkl3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--myRpum2M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719721493/V8zA4Rkl3.png" alt="getPerson.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Add Favourite&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;knex query for adding favourite&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B-amYvOx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627725960651/m8KG7yrEU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-amYvOx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627725960651/m8KG7yrEU.png" alt="personIdFav.png"&gt;&lt;/a&gt;&lt;br&gt;
testing add Favourite API&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GXqceHZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719750804/nAtHPm1bi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GXqceHZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719750804/nAtHPm1bi.png" alt="postFavourite.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*Left Join *&lt;/p&gt;

&lt;p&gt;Left join select the matching data between the left table and right table and all the records from the left table.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JRngi_oz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718783000/K9G6CPMLE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JRngi_oz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627718783000/K9G6CPMLE.png" alt="getFavJoin.png"&gt;&lt;/a&gt;&lt;br&gt;
 testing left join route with the postman&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E2FN6T0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719790498/JPlZP3QzV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E2FN6T0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627719790498/JPlZP3QzV.png" alt="getFavouriteLeftJoin.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.env Configuration used in project&lt;/strong&gt;&lt;br&gt;
 Make the necessary needed change and to able to use .env file install&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;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xze109eR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627727112263/Z85ilARh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xze109eR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627727112263/Z85ilARh2.png" alt="env.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Bvekv1/knexCrud.git"&gt;SourceCode&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devhints.io/knex"&gt;Knex Cheatsheet&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://michaelavila.com/knex-querylab/"&gt;KnexQuery to raw query&lt;/a&gt; &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
