<?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: Marco Moscatelli</title>
    <description>The latest articles on DEV Community by Marco Moscatelli (@marcomoscatelli).</description>
    <link>https://dev.to/marcomoscatelli</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%2F825877%2F0343e97b-5681-43e4-922a-1b84bd4952ae.jpg</url>
      <title>DEV Community: Marco Moscatelli</title>
      <link>https://dev.to/marcomoscatelli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcomoscatelli"/>
    <language>en</language>
    <item>
      <title>A gentle introduction to Convolutions (Visually explained)</title>
      <dc:creator>Marco Moscatelli</dc:creator>
      <pubDate>Tue, 26 Sep 2023 19:41:20 +0000</pubDate>
      <link>https://dev.to/marcomoscatelli/a-gentle-introduction-to-convolutions-visually-explained-4c8d</link>
      <guid>https://dev.to/marcomoscatelli/a-gentle-introduction-to-convolutions-visually-explained-4c8d</guid>
      <description>&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-images-1.medium.com%2Fmax%2F800%2F1%2ASVkgHoFoiMZkjy54zM_SUw.gif" 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-images-1.medium.com%2Fmax%2F800%2F1%2ASVkgHoFoiMZkjy54zM_SUw.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever asked yourself how is it possible to &lt;strong&gt;identify&lt;/strong&gt; all the horizontal lines in an image with just some scalar products between matrices? No? Me neither, but you can use &lt;strong&gt;convolutions&lt;/strong&gt; to do that, and they can do other magic things… Obviously!&lt;/p&gt;

&lt;p&gt;The ability of computers to &lt;strong&gt;recognize&lt;/strong&gt; faces, identify objects, and drive cars autonomously is based on this sort of &lt;strong&gt;mathematical operation&lt;/strong&gt; called convolution. This operation was first &lt;strong&gt;introduced&lt;/strong&gt; in the &lt;strong&gt;19th&lt;/strong&gt; century by Siméon Denis Poisson, a French mathematician and physicist.&lt;/p&gt;

&lt;p&gt;But it wasn’t until the &lt;strong&gt;1980s&lt;/strong&gt; that convolution found its way into the field of &lt;strong&gt;computer vision&lt;/strong&gt;, thanks to the pioneering work of researchers such as Yann LeCun, Geoff Hinton, and Yoshua Bengio.&lt;/p&gt;

&lt;p&gt;Since then, convolution has become a &lt;strong&gt;foundation&lt;/strong&gt; of modern machine learning, enabling computers to process images, videos, and other forms of visual data with unparalleled accuracy and efficiency.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the world of convolutions by even &lt;strong&gt;“convoluting” a duck,&lt;/strong&gt; stick with me to the end to know the power of this beautiful tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is a convolution?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Convolution is a simple &lt;strong&gt;mathematical operation&lt;/strong&gt;, it involves taking a small matrix, called &lt;strong&gt;kernel&lt;/strong&gt; or filter, and &lt;strong&gt;sliding&lt;/strong&gt; it over an input image, performing the &lt;strong&gt;dot product&lt;/strong&gt; at each point where the filter overlaps with the image, and repeating this process for all pixels.&lt;/p&gt;

&lt;p&gt;The kernel is designed to &lt;strong&gt;highlight&lt;/strong&gt; certain &lt;strong&gt;features&lt;/strong&gt; of the input image, such as edges, corners, or textures, by detecting patterns of pixels that match certain criteria.&lt;/p&gt;

&lt;p&gt;You can perform convolution in &lt;strong&gt;1D&lt;/strong&gt;, &lt;strong&gt;2D,&lt;/strong&gt; and even in &lt;strong&gt;3D&lt;/strong&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-images-1.medium.com%2Fmax%2F800%2F0%2A1CwfqZHE9fGu774w.gif" 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-images-1.medium.com%2Fmax%2F800%2F0%2A1CwfqZHE9fGu774w.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see from the GIF above that we are performing the dot product between matrices for every “&lt;strong&gt;jump&lt;/strong&gt;” of the kernel and adding that result as a new pixel in the convolution.&lt;/p&gt;

&lt;p&gt;You can use convolution both for &lt;strong&gt;upsampling&lt;/strong&gt;(increasing resolution) and for &lt;strong&gt;downsampling&lt;/strong&gt;(decreasing resolution), we’ll see later a variant of convolution that is really great for upsampling and a method for downsampling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; The goal of using &lt;strong&gt;convolution&lt;/strong&gt; in deep learning is not to use them to predict an outcome, but to &lt;strong&gt;extract&lt;/strong&gt; features that then will be used by &lt;strong&gt;FFNs&lt;/strong&gt; layers to &lt;strong&gt;predict&lt;/strong&gt; data.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to implement convolutions in Python
&lt;/h3&gt;

&lt;p&gt;For this explanation, we just need two libraries, &lt;strong&gt;PyTorch&lt;/strong&gt; and &lt;strong&gt;Matplotlib&lt;/strong&gt;.&lt;/p&gt;

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

import torch  
import torch.nn.functional as F  
import matplotlib.pyplot as plt

Let’s start by creating an image with random pixels, and a “pretty" kernel and plotting everything out:

# Creating a images 20x20 made with random value  
imgSize = 20  
image = torch.rand(imgSize, imgSize)  

# typically kernels are created with odd size   
kernelSize = 7  

# Creating a 2D image  
X, Y = torch.meshgrid(torch.linspace(-3,3,kernelSize),torch.linspace(-3,3,kernelSize))  

# This is the basic formula for a gaussian, this will make our kernel "pretty"  
kernel = torch.exp( -(X**2+Y**2)/7 )  

fig,ax = plt.subplots(1,2,figsize=(8,6))  
ax[0].imshow(image)  
ax[0].set_title('Image')  

ax[1].imshow(kernel)  
ax[1].set_title('Convolution kernel')  

plt.show()


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

&lt;/div&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-images-1.medium.com%2Fmax%2F800%2F1%2A7NuvwBuDjV1jM_aRUx2L_Q.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-images-1.medium.com%2Fmax%2F800%2F1%2A7NuvwBuDjV1jM_aRUx2L_Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn’t this kernel beautiful? Now it is time to talk about the part that you have been waiting for… The implementation of convolution.&lt;/p&gt;

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

# Pytorch requires the image and the kernel in this format:   
# (in_channels, output_channels, imgSizeY, imgSizeX)  
image_processed = image.view(1, 1, imgSize, imgSize)  
kernel_processed = kernel.view(1,1, kernelSize, kernelSize)  

# implementing the convolution  
convolution = F.conv2d(image_processed, kernel_processed)  

plt.title("Convolution")  
# we need to bring back the convolution to a format understandable by Matplotlib  
plt.imshow(convolution.view(convolution.shape[2], convolution.shape[3]))


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

&lt;/div&gt;

&lt;p&gt;You should get a result similar to this:&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-images-1.medium.com%2Fmax%2F800%2F1%2Aq4aqAkgf4MUBW6JwUpIapw.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-images-1.medium.com%2Fmax%2F800%2F1%2Aq4aqAkgf4MUBW6JwUpIapw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Time to create a “convoluted” duck!
&lt;/h4&gt;

&lt;p&gt;Don’t you think is better to use real images? We will a &lt;strong&gt;vertical&lt;/strong&gt; kernel to identify all the vertical lines and a &lt;strong&gt;horizontal&lt;/strong&gt; kernel to identify all horizontal lines, and the image will be this beautiful duck that is ready to be “convoluted”:&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-images-1.medium.com%2Fmax%2F800%2F1%2AW3tNZ3xGwXs0grkGNJ711Q.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-images-1.medium.com%2Fmax%2F800%2F1%2AW3tNZ3xGwXs0grkGNJ711Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

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

# to read an image from a url  
from imageio import imread  
# to perform an operation  
import numpy as np  

duck = imread('https://media.istockphoto.com/id/464988959/photo/mallard-duck-on-white-background.jpg?b=1&amp;amp;s=612x612&amp;amp;w=0&amp;amp;k=20&amp;amp;c=mzgsLywgUZ_mAQPWVPJgbFp68doxm5d7fXy-huiaNSY=')  
print(duck.shape) # should be (612, 530, 3)  

# transform image to 2D for convenience (not necessary for convolution!)  
# We need numpy because with torch we cannot mean over a specific axis  
duck = torch.Tensor(np.mean(duck,axis=2))  
duck = duck/torch.max(duck) # scaling the image  

# check the size again  
print(duck.shape) # should be (612, 530)


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

&lt;/div&gt;

&lt;p&gt;Time to implement the convolution on this beautiful duck:&lt;/p&gt;

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

# creating the kernels  
# vertical kernel  
VK = torch.Tensor([ [1,0,-1],  
                [1,0,-1],  
                [1,0,-1] ]).view(1, 1, 3, 3) # remember? the kernel has to have a specific format  

# horizontal kernel  
HK = torch.Tensor([ [ 1, 1, 1],  
                [ 0, 0, 0],  
                [-1,-1,-1] ]).view(1, 1, 3, 3)  

fig,ax = plt.subplots(2,2,figsize=(12,10))  

# plotting vertical kernel  
ax[0,0].imshow(VK.view(3,3))  
ax[0,0].set_title('Vertical kernel')  

# plotting horizontal kernel  
ax[0,1].imshow(HK.view(3,3))  
ax[0,1].set_title('Horizontal kernel')  

# run convolution and show the result  
convolution = F.conv2d(duck.view(1,1,duck.shape[0], duck.shape[1]),VK) # be sure to change the format  
ax[1,0].imshow(convolution.view(convolution.shape[2], convolution.shape[3]),cmap='gray',vmin=0,vmax=.01) # we scale the image using vmin and vmax  

convolution = F.conv2d(duck.view(1,1,duck.shape[0], duck.shape[1]),HK)  
ax[1,1].imshow(convolution.view(convolution.shape[2], convolution.shape[3]),cmap='gray',vmin=0,vmax=.01) # we scale the image using vmin and vmax  

plt.show()


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

&lt;/div&gt;

&lt;p&gt;Ready for the result?&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-images-1.medium.com%2Fmax%2F800%2F1%2AAz101vaeJZ9Nq9hljA-e1w.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-images-1.medium.com%2Fmax%2F800%2F1%2AAz101vaeJZ9Nq9hljA-e1w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty stunning as a result, what do you think?&lt;/p&gt;

&lt;p&gt;Here we are using a kernel invented by humans, in &lt;strong&gt;DL models&lt;/strong&gt; the kernel will be &lt;strong&gt;learned&lt;/strong&gt; by the network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notice this:&lt;/strong&gt; PyTorch and other &lt;strong&gt;DL&lt;/strong&gt; frameworks implement actually a thing called “&lt;strong&gt;cross-correlation&lt;/strong&gt;” and not convolution, but stick with me until the end to know more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploring convolutions parameters
&lt;/h3&gt;

&lt;p&gt;The most important parameters are &lt;strong&gt;stride&lt;/strong&gt; and &lt;strong&gt;padding&lt;/strong&gt;, in this article, you’ll see covered both.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add empty borders with padding!
&lt;/h4&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-images-1.medium.com%2Fmax%2F800%2F0%2A1CwfqZHE9fGu774w.gif" 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-images-1.medium.com%2Fmax%2F800%2F0%2A1CwfqZHE9fGu774w.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;padding:&lt;/strong&gt; have you noticed in this GIF there are some sort of zeros on the &lt;strong&gt;borders&lt;/strong&gt;? This is called padding, the convolution, in this case, has a padding of 1, the value from the padding can be &lt;strong&gt;any number&lt;/strong&gt; but the best value to pick is usually zero.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Increase stride if you want to jump more!&lt;/strong&gt;
&lt;/h4&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-images-1.medium.com%2Fmax%2F800%2F1%2Au1mvmQvOPgFkIKcFm-RQfA.jpeg" 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-images-1.medium.com%2Fmax%2F800%2F1%2Au1mvmQvOPgFkIKcFm-RQfA.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above made with my beautiful handwriting skills you can see that we are &lt;strong&gt;skipping&lt;/strong&gt; some numbers (I am using a kernel of size one for simplicity), this is because we have a stride &amp;gt; 1, stride is just the number of “&lt;strong&gt;jumps&lt;/strong&gt;” that the kernel will do in a direction. The image above has a stride of 2. If you want to downsample you can just increase the stride.&lt;/p&gt;

&lt;p&gt;Suppose we apply a stride of 3 while using a 3x3 kernel and a 5x5 input — what would happen on the second jump?&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-images-1.medium.com%2Fmax%2F800%2F0%2ADJxFX4ZA6guA6ylw.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-images-1.medium.com%2Fmax%2F800%2F0%2ADJxFX4ZA6guA6ylw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exactly, we &lt;strong&gt;can’t&lt;/strong&gt; make any &lt;strong&gt;operation&lt;/strong&gt; in that part, PyTorch will omit the pixel when the kernel goes outside the image, the only solution is to add padding.&lt;/p&gt;

&lt;h4&gt;
  
  
  Knowing the size of the output with convolution
&lt;/h4&gt;

&lt;p&gt;You probably know the &lt;strong&gt;size&lt;/strong&gt; of the output even before the &lt;strong&gt;output&lt;/strong&gt; is given just by looking at the parameters, but this will become more difficult as the size of the parameters increases, here’s a formula to calculate the exact size of the output:&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-images-1.medium.com%2Fmax%2F800%2F1%2AiIBsPx1dWwWZauA0n1rRaA.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-images-1.medium.com%2Fmax%2F800%2F1%2AiIBsPx1dWwWZauA0n1rRaA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;X&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: is the size of the output&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;M&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: is the size of the input&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: padding&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;K&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: kernel size&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;S&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: stride&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;h&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: horizontal or vertical&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;⌊ ⌋&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: round down&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transposed convolution
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Transposed convolution,&lt;/strong&gt; also known as deconvolution,  is a sort of convolution that is great for &lt;strong&gt;upsampling&lt;/strong&gt;, with this type of convolution we start with a small image and receive as an output a bigger image.&lt;/p&gt;

&lt;p&gt;To do that just perform a &lt;strong&gt;scalar matrix multiplication&lt;/strong&gt; between the kernel and every pixel of the image, like normal convolution even here we slide the kernel over the image, and in the result, you would &lt;strong&gt;sum&lt;/strong&gt; the &lt;strong&gt;overlapped&lt;/strong&gt; part.&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-images-1.medium.com%2Fmax%2F800%2F1%2A_g534f3feEpnEQ5MM_R1YA.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-images-1.medium.com%2Fmax%2F800%2F1%2A_g534f3feEpnEQ5MM_R1YA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Knowing the size of the output with transposed convolution&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Similar to the &lt;strong&gt;formula&lt;/strong&gt; that you have seen in the previous section there is a formula too, to calculate the &lt;strong&gt;output size&lt;/strong&gt; using transposed convolutions.&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-images-1.medium.com%2Fmax%2F800%2F1%2A3q8Pb0FVvBXQMT4fEq1TIw.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-images-1.medium.com%2Fmax%2F800%2F1%2A3q8Pb0FVvBXQMT4fEq1TIw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;X&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: is the size of the output&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;M&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: is the size of the input&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: padding&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;K&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: kernel size&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;S&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: stride&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;h&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: horizontal or vertical&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;⌊ ⌋&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: round down&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  There is something I have not told you…
&lt;/h3&gt;

&lt;p&gt;Actually, the &lt;strong&gt;deep learning&lt;/strong&gt; models implement another thing that is not convolution but it is similar, and it’s called &lt;strong&gt;cross-correlation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The only &lt;strong&gt;difference&lt;/strong&gt; between the two is that convolution uses an “&lt;strong&gt;inverted&lt;/strong&gt;” kernel, rotated by 180°.&lt;/p&gt;

&lt;p&gt;Pytorch with &lt;strong&gt;F.conv2d()&lt;/strong&gt; is implementing &lt;strong&gt;cross-correlation&lt;/strong&gt;, If you want to implement a &lt;strong&gt;real convolution&lt;/strong&gt; you can easily use the &lt;strong&gt;Scipy&lt;/strong&gt; library or create the code on your own (just remember to rotate the kernel by 180°).&lt;/p&gt;

&lt;h3&gt;
  
  
  Maximizing the performance of convolutions using pooling
&lt;/h3&gt;

&lt;p&gt;The main goal of pooling is to &lt;strong&gt;stabilize&lt;/strong&gt; the results and create a more stable network, this is because pooling increments the &lt;strong&gt;receptive fields&lt;/strong&gt; (stay with me, I’ll explain later what it means and we it is useful).&lt;/p&gt;

&lt;p&gt;With a pooling layer, you want a pixel to &lt;strong&gt;explain&lt;/strong&gt; the image as best as it can, this is made by doing an operation on a number of pixels to reduce that number to one, for example, a 4x4 block of pixels will be reduced to 1x1 block of pixels, this can be made by &lt;strong&gt;averaging&lt;/strong&gt; or taking the &lt;strong&gt;maximum&lt;/strong&gt;/&lt;strong&gt;minimum&lt;/strong&gt; value.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;pooling&lt;/strong&gt; operation takes the &lt;strong&gt;same parameters&lt;/strong&gt; as the operation of &lt;strong&gt;convolution&lt;/strong&gt;, with a small difference, here we can choose what to do if our kernel goes “outside” the image (which can be caused by a too-large stride).&lt;/p&gt;

&lt;p&gt;There are different types of pooling operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Mean&lt;/strong&gt; pooling&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Max&lt;/strong&gt; pooling&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Min&lt;/strong&gt; pooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you do with convolution, even here you &lt;strong&gt;slide&lt;/strong&gt; a sort of kernel (formally called “&lt;strong&gt;spatial extent&lt;/strong&gt;”), in the highlighted part you would take the average of all values, or the max value or the min value to represent a single pixel in the output.&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-images-1.medium.com%2Fmax%2F800%2F1%2AWvHC5bKyrHa7Wm3ca-pXtg.gif" 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-images-1.medium.com%2Fmax%2F800%2F1%2AWvHC5bKyrHa7Wm3ca-pXtg.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually, when you use pooling you would also set the &lt;strong&gt;stride&lt;/strong&gt; to be the &lt;strong&gt;same&lt;/strong&gt; as the &lt;strong&gt;spatial extent&lt;/strong&gt;, as you can see in the GIF above with the same size of two for the spatial extent and for the stride.&lt;/p&gt;

&lt;h4&gt;
  
  
  What are receptive fields?
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Receptive fields&lt;/strong&gt; are a very &lt;strong&gt;important&lt;/strong&gt; concept in psychology, signal processing and deep learning too. A receptive field is the &lt;strong&gt;quantity&lt;/strong&gt; of data in the &lt;strong&gt;field of view&lt;/strong&gt; of something, the receptive field of an &lt;strong&gt;FNN unit&lt;/strong&gt; is &lt;strong&gt;one&lt;/strong&gt; pixel.&lt;/p&gt;

&lt;p&gt;Having a receptive field of &lt;strong&gt;one&lt;/strong&gt; makes the network &lt;strong&gt;non-robust&lt;/strong&gt; to translation, resizing, rotations, etc. For example, let’s say that you take more photos of yourself in a park in the same position, these photos are similar to each other, but they have &lt;strong&gt;small differences&lt;/strong&gt;, which can cause the network to &lt;strong&gt;not recognize&lt;/strong&gt; you in both photos.&lt;/p&gt;

&lt;p&gt;So you want a pixel in the output to contain &lt;strong&gt;more information&lt;/strong&gt; than just a single square in the input.&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-images-1.medium.com%2Fmax%2F800%2F1%2Am1Ny3uKD69_pXTA4CDkovA.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-images-1.medium.com%2Fmax%2F800%2F1%2Am1Ny3uKD69_pXTA4CDkovA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above you have some little changes between the two photos, a network without a pooling layer can &lt;strong&gt;struggle&lt;/strong&gt; in &lt;strong&gt;identifying&lt;/strong&gt; you in both photos (because ANN units have a receptive field of one).&lt;/p&gt;

&lt;h4&gt;
  
  
  “Kernel” outside the image in pooling operations
&lt;/h4&gt;

&lt;p&gt;Do you remember that we have seen what would happen if we have too large stride and we go outside the image with the kernel?&lt;/p&gt;

&lt;p&gt;In a convolution you would increase padding, using pooling, you have in PyTorch a parameter called “&lt;strong&gt;ceil_mode&lt;/strong&gt;”, if set to False, you will remove the pixel created when a part of the kernel is outside the image, if set to True, the operation of pooling will be performed only on the part covered by the Kernel, but in this case, the pixel will be added to the result.&lt;/p&gt;

&lt;h4&gt;
  
  
  A typical CNN architecture is like this:
&lt;/h4&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-images-1.medium.com%2Fmax%2F800%2F1%2At96BaUwVK9t30e0cJia2ug.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-images-1.medium.com%2Fmax%2F800%2F1%2At96BaUwVK9t30e0cJia2ug.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example of CNN architecture&lt;/p&gt;

&lt;h4&gt;
  
  
  To pool or to stride?
&lt;/h4&gt;

&lt;p&gt;There is an alternative to pooling and it is to increase stride in the convolution operation, they both increase the receptive field of a neuron but there are some differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  pooling layers are &lt;strong&gt;faster&lt;/strong&gt; at the computational level&lt;/li&gt;
&lt;li&gt;  pooling layers have usually &lt;strong&gt;smaller receptive fields&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  pooling layers are usually more &lt;strong&gt;stable&lt;/strong&gt; in complex networks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no correct answer to whether you should pick one over another, pooling layers are more historical so you could find them in more architecture, but both are valid choices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;Now you know what are convolutions and their variants and how to implement them in PyTorch, you know how convolutions are used in deep learning models and how to use pooling to your advantage.&lt;/p&gt;

&lt;p&gt;You have just &lt;strong&gt;nicked&lt;/strong&gt; the &lt;strong&gt;surface&lt;/strong&gt; of the implementation of convolutions in Deep Learning, now your job is to go on this path and start learning the beautiful thing that CNNs can gift you.&lt;/p&gt;

&lt;p&gt;I want to share some resources if you want to go more in-depth in this argument:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.youtube.com/watch?v=KuXjwB4LzSA&amp;amp;t=146s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=KuXjwB4LzSA&amp;amp;t=146s&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/towards-artificial-intelligence/convolutional-neural-networks-cnns-tutorial-with-python-417c29f0403f" rel="noopener noreferrer"&gt;https://medium.com/towards-artificial-intelligence/convolutional-neural-networks-cnns-tutorial-with-python-417c29f0403f&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.udemy.com/course/deeplearning_x/" rel="noopener noreferrer"&gt;https://www.udemy.com/course/deeplearning_x/&lt;/a&gt; (most of what you see in this article is taken from this course) Mike X Cohen is one of the best teachers on Udemy.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How MongoDB works behind the scenes</title>
      <dc:creator>Marco Moscatelli</dc:creator>
      <pubDate>Mon, 14 Mar 2022 15:20:54 +0000</pubDate>
      <link>https://dev.to/marcomoscatelli/how-mongodb-works-behind-the-scenes-3474</link>
      <guid>https://dev.to/marcomoscatelli/how-mongodb-works-behind-the-scenes-3474</guid>
      <description>&lt;p&gt;Databases are an essential part of development, but how do they work? In this article, I will show you how a no-SQL database like MongoDB works behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is a database?&lt;/li&gt;
&lt;li&gt;What is MongoDB?&lt;/li&gt;
&lt;li&gt;SQL vs no-SQL databases&lt;/li&gt;
&lt;li&gt;What is JSON?&lt;/li&gt;
&lt;li&gt;What the hell is BSON?&lt;/li&gt;
&lt;li&gt;What is Mongoose?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What is a database?
&lt;/h2&gt;

&lt;p&gt;A database is a set of structured information (or data) typically stored electronically in a computer system. Usually, the database is controlled by a database management system (DBMS). Data, the DBMS, and associated applications are referred to as a database system, often abbreviated to database only.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What is MongoDB?
&lt;/h2&gt;

&lt;p&gt;MongoDB is an open-source, non-relational database management system that processes and stores many types of data using flexible documents rather than tables and rows. MongoDB, being a NoSQL solution, does not need a relational database management system, hence it offers an elastic data storage format that allows users to easily store and query multiple data types. This not only makes database administration easier for developers but also enables a highly scalable environment for cross-platform applications and services.&lt;/p&gt;

&lt;p&gt;The basic units of data in MongoDB are documents or groups of documents. These documents, which are formatted as Binary JSON (JavaScript Object Notation), may hold many sorts of data and be transferred across multiple platforms. Because MongoDB has a dynamic schema architecture, users have unprecedented freedom when generating data records, querying document collections using MongoDB aggregation, and analyzing enormous volumes of data.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. SQL vs no-SQL databases
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The following table outlines the key differences between SQL and NoSQL databases.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SQL Databases&lt;/th&gt;
&lt;th&gt;NoSQL Databases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Storage Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tables with fixed rows and columns&lt;/td&gt;
&lt;td&gt;Document: JSON documents, Key-value: key-value pairs, Wide-column: tables with rows and dynamic columns, Graph: nodes and edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Development History&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developed in the 1970s with a focus on reducing data duplication&lt;/td&gt;
&lt;td&gt;Developed in the late 2000s with a focus on scaling and allowing for rapid application change driven by agile and DevOps practices.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Oracle, MySQL, Microsoft SQL Server, and PostgreSQL&lt;/td&gt;
&lt;td&gt;Document: MongoDB and CouchDB, Key-value: Redis and DynamoDB, Wide-column: Cassandra and HBase, Graph: Neo4j and Amazon Neptune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;General purpose&lt;/td&gt;
&lt;td&gt;Document: general purpose, Key-value: large amounts of data with simple lookup queries, Wide-column: large amounts of data with predictable query patterns, Graph: analyzing and traversing relationships between connected data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schemas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rigid&lt;/td&gt;
&lt;td&gt;Flexible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vertical (scale-up with a larger server)&lt;/td&gt;
&lt;td&gt;Horizontal (scale-out across commodity servers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-Record ACID Transactions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Most do not support multi-record ACID transactions. However, some—like MongoDB—do.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Joins&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Typically required&lt;/td&gt;
&lt;td&gt;Typically not required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data to Object Mapping&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Requires ORM (object-relational mapping)&lt;/td&gt;
&lt;td&gt;Many do not require ORMs. MongoDB documents map directly to data structures in most popular programming languages.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;JSON, or JavaScript Object Notation, was developed as part of the JavaScript language in the early 2000s by JavaScript developer Douglas Crockford, however, the format wasn't officially standardized until 2013.&lt;/p&gt;

&lt;p&gt;Javascript objects are simple associative containers, where a string key is mapped to a value (which can be a number, string, function, or even another object). Because of this fundamental language feature, JavaScript objects might be expressed in text in a wonderfully simple way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"numberOfStates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;208&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"states"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Italy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Spain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Germany"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Canada"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON began to take on a life of its own when JavaScript became the industry standard for client-side web development. JSON quickly spread beyond the web page and into software everywhere because it is both human- and machine-readable, and it is relatively easy to develop support for in other languages.&lt;/p&gt;

&lt;p&gt;JSON shows up in many different cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Configuration files&lt;/li&gt;
&lt;li&gt;Log messages&lt;/li&gt;
&lt;li&gt;Database storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON rapidly overtook XML, as it is more difficult to comprehend for humans, far more verbose, and less well suited to describing object structures in current computer languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. What the hell is BSON?
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Why BSON?
&lt;/h4&gt;

&lt;p&gt;MongoDB was created to be the ultimate data platform for modern app development. When it came to data structures, JSON was the first option.&lt;/p&gt;

&lt;p&gt;However, JSON has many drawbacks that make it unsuitable for use in databases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;JSON is a text-based format, and processing text takes a long time.&lt;/li&gt;
&lt;li&gt;Another database problem is that JSON's readable format is inefficient in terms of space.&lt;/li&gt;
&lt;li&gt;Only a few fundamental data types are supported by JSON.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;BSON was created to bridge the gap between making MongoDB JSON-first while still being high-performance and general-purpose. BSON is a binary representation for data storage in JSON format that is designed for speed, space, and flexibility.&lt;/p&gt;

&lt;h4&gt;
  
  
  So Marco, what really is BSON?
&lt;/h4&gt;

&lt;p&gt;BSON stands for "Binary JSON," which is precisely what it was created for. The binary structure of BSON encodes type and length information, making it considerably easier to understand.&lt;/p&gt;

&lt;p&gt;BSON has been enhanced since its inception to include various optional non-JSON-native data types, including dates and binary data, without which MongoDB would have been without some essential functionality.&lt;/p&gt;

&lt;p&gt;Different sized integers (ints versus longs) or different levels of decimal precision are common in languages that enable any type of complicated mathematics (float, double, decimal128, etc.).&lt;/p&gt;

&lt;p&gt;Not only is it useful to be able to describe those distinctions in MongoDB data, but it also enables direct comparisons and computations on data, which simplifies consuming application code.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is the choice of MongoDB?
&lt;/h4&gt;

&lt;p&gt;Although MongoDB stores data in BSON format both internally and across the network, you can still think of it as a JSON database. Anything that can be represented in JSON may be stored natively in MongoDB and retrieved in JSON as well.&lt;/p&gt;

&lt;h4&gt;
  
  
  JSON vs BSON
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;JSON&lt;/th&gt;
&lt;th&gt;BSON&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Encoding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UTF-8 String&lt;/td&gt;
&lt;td&gt;Binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;String, Boolean, Number, Array&lt;/td&gt;
&lt;td&gt;String, Boolean, Number (Integer, Float, Long, Decimal128...), Array, Date, Raw Binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Readability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Human and Machine&lt;/td&gt;
&lt;td&gt;Machine Only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;BSON differentiates from JSON in that it allows for the storage of some more complex sorts of data. JavaScript, for example, does not distinguish between integers (round numbers) and floating-point numbers (which have decimal precision to various degrees)&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What is Mongoose ?
&lt;/h2&gt;

&lt;p&gt;Mongoose is a MongoDB Object Data Modeling (ODM) framework written in Node.js. It is analogous to an Object Relational Mapper (ORM) for standard SQL databases, such as SQLAlchemy. Mongoose tries to tackle the problem of allowing developers to impose a specified schema at the application layer. Mongoose, in addition to enforcing a schema, provides several hooks, model validation, and other features targeted at making it simpler to interact with MongoDB.&lt;/p&gt;

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

&lt;p&gt;Now you know how MongoDB works behind the scenes, in my opinion, it is really important to know what happens behind the code, this is because you can solve faster errors regarding your applications. I hope you like this post and if yes come to check at &lt;a href="https://github.com/MoscatelliMarco"&gt;my Github page&lt;/a&gt; and my &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api"&gt;new project.&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Monetize your api using Stripe Mongoose Api</title>
      <dc:creator>Marco Moscatelli</dc:creator>
      <pubDate>Sun, 13 Mar 2022 20:03:29 +0000</pubDate>
      <link>https://dev.to/marcomoscatelli/monetize-your-api-using-stripe-mongoose-api-4k1o</link>
      <guid>https://dev.to/marcomoscatelli/monetize-your-api-using-stripe-mongoose-api-4k1o</guid>
      <description>&lt;p&gt;We live in a world so immersed in digital where a web api can create a million dollar business, in this article I will show you how to monetize your api with a library called &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api"&gt;Stripe Mongoose Api&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up your project
&lt;/h3&gt;

&lt;h4&gt;
  
  
  requirements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB installed on your computer or an online MongoDB cluster&lt;/li&gt;
&lt;li&gt;A Stripe account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First we need to install all the dependencies:&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 stripe-mongoose-api stripe mongoose express ejs 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can start building our own project, I will guide you step by step: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create app.js and userModel.js&lt;/li&gt;
&lt;li&gt;Create a model in userModel.js&lt;/li&gt;
&lt;li&gt;Add mongoose connection&lt;/li&gt;
&lt;li&gt;Express set up&lt;/li&gt;
&lt;li&gt;Basic routing&lt;/li&gt;
&lt;li&gt;Adding Stripe Mongoose Api feautures&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You'll find the source code &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api/tree/master/test"&gt;here.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create user.js and userModel.js
&lt;/h4&gt;

&lt;p&gt;Create a folder using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir &amp;lt;folderName&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create new files in the folder: app.js and userModel.js (you can name this file whatever you want but is a convention to name this file like this)&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create a model in userModel.js
&lt;/h4&gt;

&lt;p&gt;We will create a very simple schema with no schema fields to simplify our work, but you can just add whatever field you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiSystem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stripe-mongoose-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiSystem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;&amp;lt;options&amp;gt;&lt;/code&gt; field you must provide an object that contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;stripeSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your stripe secret key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;webhookSign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your stripe webhook sign key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;priceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;the price id of your product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This are the 'must provide' options but you can just check the &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api"&gt;documentation&lt;/a&gt; and choose what other options to add.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Add mongoose connection
&lt;/h4&gt;

&lt;p&gt;Let's move into app.js, add this code to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MONGO_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your MongoDB uri&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MONGO_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;useNewUrlParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;useUnifiedTopology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Database connected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./userModel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now if you try to run the file and all went well you will see in the console: 'Database connected'.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Express set up
&lt;/h4&gt;

&lt;p&gt;Require and run express:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rawBody&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;express.json is a must have middleware for this project because without this Stripe Mongoose Api cannot understand the webhook requests.&lt;br&gt;
Add the views:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ejs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;view engine&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;views&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;views&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a views folder and name it views using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Copy this &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api/blob/master/test/views/home.ejs"&gt;.ejs file&lt;/a&gt; inside the folder, it is a simple html page that will give you all the functionality provided by Stripe Mongoose Api.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Basic routing
&lt;/h4&gt;

&lt;p&gt;Routers are necessary for the functioning of the api as they will be able to receive and process requests made by users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Just rendering the home page&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// This route will redirect the user to the stripe checkout&lt;/span&gt;
&lt;span class="c1"&gt;// page, if you don't pass a user as first param, the&lt;/span&gt;
&lt;span class="c1"&gt;// method will create a new one for you&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribeUser&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// This route listen to all requests sent by stripe, it&lt;/span&gt;
&lt;span class="c1"&gt;// listens for completed checkout and for cancelled&lt;/span&gt;
&lt;span class="c1"&gt;// subscriptions&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/webhook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt;  &lt;span class="nx"&gt;user&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
  &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// This route will listen to all requests sent by the users,&lt;/span&gt;
&lt;span class="c1"&gt;// it checks if the apiKey provided is valid and if yes, will&lt;/span&gt;
&lt;span class="c1"&gt;// create a usage record and then send the data in the second&lt;/span&gt;
&lt;span class="c1"&gt;// argument&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;italy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hi from italy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// This route will send back the customer records&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/usage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt;  &lt;span class="nx"&gt;user&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customerRecords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// This route create a new api key for the user and&lt;/span&gt;
&lt;span class="c1"&gt;// destroy the old one&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/changeapikey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt;  &lt;span class="nx"&gt;user&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt;  &lt;span class="nx"&gt;key&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changeApiKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;  &lt;span class="nx"&gt;PORT&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;  &lt;span class="o"&gt;||&lt;/span&gt;  &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Serving on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now you are ready to run &lt;code&gt;node app.js&lt;/code&gt; and see your app working properly, now you know how simple can be to create an api and monetize it using Stripe Mongoose Api.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;Stripe Mongoose Api is a project made by me and i put in a lot of hard work, Stripe Mongoose Api will receive continuous updates so check the &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api"&gt;github repo&lt;/a&gt; in case of new content, i hope you liked this tutorial, if yes please leave me a &lt;a href="https://github.com/MoscatelliMarco/stripe-mongoose-api"&gt;star&lt;/a&gt; and why not a &lt;a href="https://github.com/MoscatelliMarco"&gt;follow&lt;/a&gt; on github, &lt;strong&gt;see you next time!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
