<?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>Forem: Suyash K.</title>
    <description>The latest articles on Forem by Suyash K. (@suyious).</description>
    <link>https://forem.com/suyious</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%2F954105%2F15f21303-be10-4cfb-b979-65d7b201dd0f.jpeg</url>
      <title>Forem: Suyash K.</title>
      <link>https://forem.com/suyious</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/suyious"/>
    <language>en</language>
    <item>
      <title>Django Test Driven Social Media REST API - Getting Started</title>
      <dc:creator>Suyash K.</dc:creator>
      <pubDate>Wed, 08 Feb 2023 11:57:03 +0000</pubDate>
      <link>https://forem.com/suyious/django-test-driven-social-media-rest-api-getting-started-1j47</link>
      <guid>https://forem.com/suyious/django-test-driven-social-media-rest-api-getting-started-1j47</guid>
      <description>&lt;h3&gt;
  
  
  Basic Project Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;DjangoRESTAPI &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nb"&gt;.&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install &lt;/span&gt;django djangorestframework
pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
git init
curl https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .gitignore
django-admin startproject config &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should set up a boilerplate project with project configs and initialized git repository.&lt;br&gt;
The Project Structure should resemble the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;tree &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--gitignore&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="s2"&gt;".git/"&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt;
├── .gitignore
├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt 
&lt;span class="nv"&gt;asgiref&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;3.6.0
backports.zoneinfo&lt;span class="o"&gt;==&lt;/span&gt;0.2.1
&lt;span class="nv"&gt;Django&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;4.1.6
&lt;span class="nv"&gt;djangorestframework&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;3.14.0
&lt;span class="nv"&gt;pytz&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;2022.7.1
&lt;span class="nv"&gt;sqlparse&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;0.4.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initial Commit: Getting Started
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src/user
&lt;span class="nb"&gt;touch &lt;/span&gt;src/__init__.py
python3 manage.py startapp user src/user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Project Structure should resemble the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;tree src/
src/
├── __init__.py
└── user
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to add the user app to the project, edit &lt;code&gt;src/user/apps.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.apps&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AppConfig&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppConfig&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;default_auto_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.models.BigAutoField&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;src.user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then edit &lt;code&gt;config/settings.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...
&lt;/span&gt;
&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.contrib.admin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;src.user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run migrations and start the development server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should start the development server on localhost. Now we can open the project in the code editor. Also we can commit our changes to the git repository.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>developer</category>
      <category>ai</category>
      <category>openai</category>
    </item>
    <item>
      <title>Your files go to Cloud : Uploading Images with Express to Cloudinary</title>
      <dc:creator>Suyash K.</dc:creator>
      <pubDate>Sat, 19 Nov 2022 18:25:15 +0000</pubDate>
      <link>https://forem.com/suyious/your-files-go-to-cloud-uploading-images-with-express-to-cloudinary-3k2</link>
      <guid>https://forem.com/suyious/your-files-go-to-cloud-uploading-images-with-express-to-cloudinary-3k2</guid>
      <description>&lt;p&gt;As soon as your website or app reaches a point when you realize you cannot always display static or dummy images among all the dynamic content fetched from your backend, you start looking for ways to integrate image uploads in your project. After looking around on the internet for a while, you begin to hear some names and if you aren't willing to let AWS have your card details, you will fall back to &lt;a href="https://cloudinary.com" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt;. Now, Cloudinary is quite convenient for small project and specially when you are still studying. But last time I tried getting it set up in my project, it wasn't the most "copy-from-docs and go" set up. Along with Cloudinary's own configuration, an important aspect is how you actually bring your files to Cloudinary's API for the upload.&lt;/p&gt;

&lt;p&gt;In this one, we will be implementing image uploads to cloudinary wherein we will demonstrate it using a form to set profile pictures for the user. Our focus here would be on how we will handle the file so that it can be uploaded. I will use a node.js backend with authentication already implemented. In the client, I will use a form that handle user's profile information but we mostly care about the profile picture. &lt;/p&gt;

&lt;h3&gt;
  
  
  Preface
&lt;/h3&gt;

&lt;p&gt;I will be going in depth in this one. If you need a to-the-point solution to how you can get image upload set-up with cloudinary you can skip to In short&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get started
&lt;/h3&gt;

&lt;p&gt;So, I am trying to add a profile picture to the users in my database by uploading them to cloudinary. I would have a form in the front end, I would use a file input to select a file and then it would send this file to the backend where it would be uploaded to cloudinary. Now, these things come with hidden complexities at each steps. The file input gives us a Javascript &lt;code&gt;File&lt;/code&gt; Object which the database or cloudinary doesn't really like or understand. We need raw image data or maybe a url. Also, JSON wouldn't send images as it is basically just fancy text. Even if we do manage to send these File Objects to our endpoint, this file object would not be enough to upload the image to cloudinary. Let's test each of these using an express server and a mongodb database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Situation
&lt;/h3&gt;

&lt;p&gt;I have a user collection in my local mongodb and I have added one user to it manually which looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogdb&amp;gt; db.users.find()
[
  {
    _id: ObjectId("629f08b134f91b645470ca97"),
    username: 'suyious',
    name: 'Suyash Kumar',
    email: 'solo@gmail.com',
    password: '$2b$10$eT7nsqWx3jVjlH9xbHOU2.EcowoHlXf8VWMldb2klFKL2CzxSeC5a',
    role: 'user',
    createdAt: ISODate("2022-06-07T08:13:37.436Z"),
    __v: 0,
    avatar: {
      public_id: 'xetra/products/vunlvjcijttmyu6aah1o',
      url: 'https://res.cloudinary.com/djv5txrzp/image/upload/v1667916852/xetra/products/vunlvjcijttmyu6aah1o.jpg'
    }
  }
]

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

&lt;/div&gt;



&lt;p&gt;This should give an idea of how the user collection looks like. We have an &lt;code&gt;avatar&lt;/code&gt; field which is an object with a key &lt;code&gt;url&lt;/code&gt;. Now I would like to change this avatar field and by changing it, I imply sending an image from my frontend to the server which would then get uploaded to cloudinary and the &lt;code&gt;avatar&lt;/code&gt; field would have it's new &lt;code&gt;url&lt;/code&gt;. Now we can always manually upload our images to cloudinary and just send it's url through a JSON, but we need that to happen on it's own and we should just need to use the html file input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending the image from the frontend
&lt;/h3&gt;

&lt;p&gt;I guess even now, you would have started getting a hint that JSON would probably not send our file object to our server. But, let's test that anyway. All we need is an &lt;code&gt;&amp;lt;input type="file"/&amp;gt;&lt;/code&gt; and an &lt;code&gt;axios.put('/upload', body)&lt;/code&gt;. When we are sending the image from the frontend, the request body looks like the following in Javascript:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F04kp7g15v0ic539lnyde.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F04kp7g15v0ic539lnyde.png" alt="Browser Javascript console showing our request body"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks fine for now but as soon as this request reaches the backend, thing begin to look different.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2ixbseq4u2fc29i3pw9.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2ixbseq4u2fc29i3pw9.png" alt="Server Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clearly, JSON doesn't seem to know what a file exactly is. Guess, it's time to run to stack overflow.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1gf2yn46ql47k1twqur.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1gf2yn46ql47k1twqur.png" alt="Naruto run meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Turns out, apart from &lt;code&gt;application/json&lt;/code&gt;, there are other content-type for your request body and one of them is &lt;a href="https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean" rel="noopener noreferrer"&gt;&lt;code&gt;mutipart/form-data&lt;/code&gt;&lt;/a&gt;. In short, this is what we use when we have files along with text to send to server. Looks like that should solve our problem and the &lt;code&gt;File&lt;/code&gt; would show up in our backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  multipart/form-data
&lt;/h3&gt;

&lt;p&gt;In order to send &lt;code&gt;multipart/form-data&lt;/code&gt; through an HTMl form, you need &lt;code&gt;&amp;lt;form enctype='multipart/form-data'&amp;gt;&lt;/code&gt; tag and when using axios, you need &lt;code&gt;axios.put('/put', body, { "Content-Type": "multipart/form-data" })&lt;/code&gt;. You can also create a &lt;code&gt;FormData&lt;/code&gt; Object in Javascript and set key/value pairs to construct your request body.&lt;/p&gt;

&lt;p&gt;So, now we should just try sending form-data from our frontend similar to before, only this time our request body would be constructed using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const body = new FormData(formElement);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;formElement&lt;/code&gt; is a reference to am html form which can be the name of a form ( or ref.current when using React.useRef)&lt;/p&gt;

&lt;p&gt;In the frontend, the request body looks like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qv6eeyj0da4re8jia87.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qv6eeyj0da4re8jia87.png" alt="Javascript console req.body"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now, we turn to our server only to see an even more obscure 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fecryo1c359awchrigd1g.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fecryo1c359awchrigd1g.png" alt="Server Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We should also try to send the same form-data using postman just in case we are making some mistake in our frontend code.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiba6yy0c287qpc7l2mz5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiba6yy0c287qpc7l2mz5.png" alt="Postman Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clearly, even postman gives us a similar output. It seems like the backend isn't able to understand what we are throwing at it. Hmm. That doesn't happen often. Or does it? One might begin to remember that we couldn't earlier even read the JSON output if we just threw it at the backend. If that didn't ring a bell, I am talking about the &lt;code&gt;express.json()&lt;/code&gt; or earlier &lt;code&gt;bodyparser()&lt;/code&gt; middlewares that we needed to parse our JSON requests. It is fairly obvious that we would also need to parse form-data before our backend can understand it.&lt;/p&gt;

&lt;p&gt;Now, there are multiple similar libraries for accomplishing this and the most famous one that I can find is &lt;a href="https://www.npmjs.com/package/multer" rel="noopener noreferrer"&gt;&lt;code&gt;multer&lt;/code&gt;&lt;/a&gt;. Naturally, we would start by installing it and including it in our server. We could add the middleware for every route similar to &lt;code&gt;express.json()&lt;/code&gt; with &lt;code&gt;express.use()&lt;/code&gt;, but we would want to only add it for the routes that actually need form data.&lt;/p&gt;
&lt;h3&gt;
  
  
  multer
&lt;/h3&gt;

&lt;p&gt;So, if we go forward, install multer and add a middleware &lt;code&gt;multer().single('avatar')&lt;/code&gt; (see &lt;a href="https://www.npmjs.com/package/multer#usage" rel="noopener noreferrer"&gt;docs&lt;/a&gt;) to our upload route, we find this in our console:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7un8j26vvgq84vbr3uk6.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7un8j26vvgq84vbr3uk6.png" alt="Server Console Logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like our form-data did pass through. But where is the file. Turns out the files are not a part of &lt;code&gt;req.body&lt;/code&gt;. Instead they are in &lt;code&gt;req.file&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwqpjvwxhrcgtiw14cvh.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwqpjvwxhrcgtiw14cvh.png" alt="Console log with File"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can finally see our file reach the backend. This looks good. Now all we have to do is throw this file at Cloudinary and it should just work out of the box. Right? Well, we all know our history with throwing things around here.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cloudinary
&lt;/h3&gt;

&lt;p&gt;Now, let's install &lt;code&gt;cloudinary&lt;/code&gt; and set it up with the configurations. You need following environment variables for the config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above is also the code that you need to add to your server for initial configuration of cloudinary. Once this is done, you should be able to talk to your cloudinary account. ( If it wasn't obvious, you need to create an account. It won't charge you or ask for card details. You will get your &lt;code&gt;api_key&lt;/code&gt; and &lt;code&gt;api_secret&lt;/code&gt; from the &lt;a href="https://cloudinary.com/console" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, as from the &lt;a href="https://cloudinary.com/documentation/node_integration#installation_and_setup" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, we need the following to upload our image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { v2 as cloudinary } from 'cloudinary'
cloudinary.uploader
  .upload(file, options)
  .then(callback);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we are set up, we should try to use the file we received from the frontend on the &lt;code&gt;upload&lt;/code&gt; function provided by the api. I have the following code added to my upload route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudinary.uploader.upload(req.file)
  .then((result =&amp;gt; {
    console.log(result);
  }))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, the server gives us a new error. Depending on how your server is set up, the error might show up at different places. As for me, the error comes as a 500 Error Response.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72zrpj9ivid3dmp64j37.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72zrpj9ivid3dmp64j37.png" alt="Javacript Console Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The error message tells us that cloudinary's API does not accept a Javascript &lt;code&gt;File&lt;/code&gt; object and instead is asking for some string. If we look into the docs again, we find the following:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf7gx8s5iz6zem5kkwfa.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf7gx8s5iz6zem5kkwfa.png" alt="Cloudinary API docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given above, the &lt;code&gt;upload&lt;/code&gt; function takes only the allowed types as the file parameter. Out of these, we do not have a local file path in the server as the file comes from the frontend. Neither do we have a file URL or S3 bucket URL. We are left with using a byte-array buffer or a Data URI (Base64 encoded).&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwqpjvwxhrcgtiw14cvh.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwqpjvwxhrcgtiw14cvh.png" alt="Console log with File"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see above, we do seem to be getting a buffer key in the file object received. Let's inspect it's value and see if it can be of our use. If we just plug the buffer value to the &lt;code&gt;upload&lt;/code&gt; function, the cloudinary api still cannot process it and gives a similar error.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixxzj5roh206nmmyb7j8.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixxzj5roh206nmmyb7j8.png" alt=" Javascript Console "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could try to process this byte array and make it work with the API but if we look at &lt;code&gt;multer&lt;/code&gt;'s &lt;a href="https://www.npmjs.com/package/multer#memorystorage" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, we notice using the buffer option requires storing the images into memory which could be bad for the server in terms of performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/multer#memorystorage" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnitaiafkciogfhtsq52r.png" alt="multer documentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we are left with either trying to convert the file into a byte-array in the frontend or using the data URI option. Also, we should try to do the computations in the frontend itself as much as possible, now that we are reminded. &lt;/p&gt;

&lt;p&gt;If we dig around a little to find some information about byte-array or Data URI, we come across the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader" rel="noopener noreferrer"&gt;&lt;code&gt;FileReader&lt;/code&gt;&lt;/a&gt; object provided by Javacript's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/File_API" rel="noopener noreferrer"&gt;&lt;code&gt;File&lt;/code&gt;&lt;/a&gt; API. This object provides functions for dealing with both byte-arrays and Data URIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  FileReader
&lt;/h3&gt;

&lt;p&gt;This &lt;code&gt;FileReader&lt;/code&gt; object delivers the data using events, as reading from disk may take time. The Syntax for using it is generally of the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reader = new FileReader();

reader.onload = () =&amp;gt; {
  &amp;lt;your-processing-function&amp;gt;(reader.result);
}

reader.&amp;lt;instance function&amp;gt;(blob);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should try the &lt;code&gt;readAsDataURL(file)&lt;/code&gt; function to send the image file as a Data URI. Note that the function is &lt;code&gt;readAsDataURL&lt;/code&gt; and NOT readAsDataURI. The result of this function call returned through &lt;code&gt;reader.result&lt;/code&gt; can also be used with &lt;code&gt;&amp;lt;img src=""/&amp;gt;&lt;/code&gt; to preview the image. The following code demonstrate how we would process the file before sending it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reader = new FileReader();
reader.onload = () =&amp;gt; {
  console.log(reader.result);
}
reader.readAsDataURL(input.files[0])

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

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;input&lt;/code&gt; may be &lt;code&gt;e.target&lt;/code&gt; if you are listening to events on a file input or &lt;code&gt;inputref.current&lt;/code&gt; if inputref is a ref to an input element when using &lt;code&gt;React.useRef&lt;/code&gt;. The resulting Data URI is returned as a string through &lt;code&gt;reader.result&lt;/code&gt;. Now, that this is a string, it should work as an argument to cloudinary API's &lt;code&gt;upload&lt;/code&gt; function.&lt;br&gt;
The result looks like the following:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5isrltxcevinq1eq8gn.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5isrltxcevinq1eq8gn.png" alt="Data URI string"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is basically a bunch of gibberish to us but will represent our image file to the server. When we send this new Data URI string to the server, it gets sent as is, that is as a string. But now that it is no longer a file. It is part of &lt;code&gt;req.body&lt;/code&gt; itself and not of the &lt;code&gt;req.file&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq1qs7vkprmnoqd1ga8z.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq1qs7vkprmnoqd1ga8z.png" alt="Server Console"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqzsxh74ipg4dhgzb3h2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqzsxh74ipg4dhgzb3h2.png" alt="Server Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we could plug this string into cloudinary API's upload function and see if it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudinary.uploader.upload(req.body.avatar)
  .then((result =&amp;gt; {
    console.log(result);
  }))

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

&lt;/div&gt;



&lt;p&gt;This, after all this work, actually works and we get the following result in our server console:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5bsst4udfwdhc98mbix.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5bsst4udfwdhc98mbix.png" alt="Server Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can go to the provided secure url and it is actually uploaded to cloudinary. We can also see this image in our cloudinary &lt;a href="https://cloudinary.com/console/media_library/folders/home" rel="noopener noreferrer"&gt;media library&lt;/a&gt;. Here, I have used the &lt;code&gt;folder&lt;/code&gt; option that can be provided in the second argument of the upload function as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const result = await cloudinary.uploader
  .upload(req.body.avatar, {
    folder: "/fraise/avatars"
  })

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxp4wx26rktu514txeil0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxp4wx26rktu514txeil0.png" alt="Cloudinary Library"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API returns an object with a url for the uploaded image as &lt;code&gt;secure_url&lt;/code&gt;, which can now be stored in the database to update our user profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user = await User.findByIdAndUpdate(req.user.id, req.body, {
  new: true,
  runValidators: true,
  useFindAndModify: false
})

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

&lt;/div&gt;



&lt;p&gt;Here, my server is setting &lt;code&gt;req.user&lt;/code&gt; while validating authentication, though it is only the providing the &lt;code&gt;id&lt;/code&gt; of the entry to update in our database. This updates the current user's profile picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  In short
&lt;/h3&gt;

&lt;p&gt;In short, all I did all this while was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send files as form-data and not JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;here you might need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form enctype='multipart/form-data'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.put('/put', body, { "Content-Type": "multipart/form-data" })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;receive form-data using multer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you might need to install &lt;code&gt;multer&lt;/code&gt; and add the middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multer().single('name')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for other usages, here's the &lt;a href="https://www.npmjs.com/packages/multer#usage" rel="noopener noreferrer"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setup cloudinary and upload
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET
})
&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;import { v2 as cloudinary } from 'cloudinary'
cloudinary.uploader
  .upload(path, options)
  .then(callback);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;send files as dataURI for the &lt;code&gt;path&lt;/code&gt; in &lt;code&gt;upload()&lt;/code&gt; above:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reader = new FileReader();
reader.onload = () =&amp;gt; {
  console.log(reader.result);
}
reader.readAsDataURL(input.files[0])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But this makes me think
&lt;/h3&gt;

&lt;p&gt;Even though we used &lt;code&gt;multer&lt;/code&gt; to be able to read multipart/form-data in the server, we don't quite seem to have used it for actual file transfer between the frontend and the backend. It makes me wonder if using form-data was for nothing. I did try to use JSON for the same but it didn't quite seem to work. Now, I didn't want to pull apart all that code again. So, I urge you to try it.&lt;/p&gt;

&lt;p&gt;Additionally, the data URI seems to be a very long string which might be too long to send back and forth. Tell me if there are other simpler ways to upload the images. I do know of another method, creating a temporary file on the server and using it's file path for the upload. This would require creating and removing files on the server.&lt;/p&gt;

&lt;p&gt;I would be really happy if I am pointed to a better direction here, but if my solution was helpful to you, that would make me really happy too.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Storing &amp; Rendering Blogs: no markdown-parser</title>
      <dc:creator>Suyash K.</dc:creator>
      <pubDate>Sat, 05 Nov 2022 16:14:29 +0000</pubDate>
      <link>https://forem.com/suyious/storing-rendering-blogs-no-markdown-parser-1i4k</link>
      <guid>https://forem.com/suyious/storing-rendering-blogs-no-markdown-parser-1i4k</guid>
      <description>&lt;p&gt;I've been trying to put together a blog for myself and a point comes when one needs to start thinking about strategies to store the blogs somewhere. One common strategy you find in a lot of tutorials is using some third-party library that parses markdown to the desired semantic, for eg. &lt;a href="https://www.npmjs.com/package/react-markdown" rel="noopener noreferrer"&gt; &lt;code&gt;react-markdown&lt;/code&gt; &lt;/a&gt;. Now, speaking of the goods of such a library, it (hopefully) tackles the security concerns that come with letting external HTML render on a site. This is the security concern that leads to &lt;em&gt;dangerous&lt;/em&gt; function names such as &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;, quoting the &lt;a href="https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml" rel="noopener noreferrer"&gt; react docs &lt;/a&gt;, just " to remind yourself that it’s dangerous " . On a serious note, &lt;a href="https://en.wikipedia.org/wiki/Cross-site_scripting" rel="noopener noreferrer"&gt;XSS attacks&lt;/a&gt; can be a major pain in the posterior. Apart from that, such libraries also eliminate the need to implement your own markdown parser.&lt;/p&gt;

&lt;p&gt;That being said, I have this little itch to &lt;strong&gt;NOT&lt;/strong&gt; use such a library for my blog. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7in0d3zxli8zkumhjyf.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7in0d3zxli8zkumhjyf.jpg" alt="I'm not in danger, I am the danger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using such a third-party library would mean adding to your dependency tree and also succumbing to making your whole site rely on its maintenance. Also, using it might be very practical for a client project but I am looking forward to learning something here and I think I am pretty skilled already in &lt;code&gt;npm i &amp;lt;package&amp;gt;&lt;/code&gt; and copying boilerplate from the documentation.&lt;/p&gt;

&lt;p&gt;In this article, however, we should just focus on the strategies for implementing text processing in the blog to have basic formatting capabilities and for creating a good enough schema for storing it in a database. If I succeed, you should see this become a 10-part series or more. 🤓&lt;/p&gt;

&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;Before moving any further, let me clarify that although the text-parsing mainly happens in the frontend, I would also be speaking about how various things are done in a node-express backend. But this isn't meant for people who are completely new to &lt;code&gt;express&lt;/code&gt; or backend in general. I would expect awareness about REST APIs and how it is implemented in &lt;code&gt;express&lt;/code&gt; from the readers. Additionally, we will probably also be talking about regular expressions ( Perl-compatible ) in javascript. If you think you don't fit in here, let me point you to some resources to get you ready!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST APIs and Express: &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=-MTSQjw5DrM" rel="noopener noreferrer"&gt;short video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Regular Expressions: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=sXQxhojSdZM" rel="noopener noreferrer"&gt;short video&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's begin
&lt;/h2&gt;

&lt;p&gt;We first need to plan how we store the blogs in a database. Rather than storing completely as a secondary markup language that needs parsing, I would like to store it in a format the database is more familiar with. Assuming that we are using a NoSQL document database like MongoDB, we can start drawing a rough picture of our model as a JSON. The same can also easily be translated into a relational table. However, for simplicity, we stick to JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogModel = {
  author : user
  created at: date
  title: string
  tags: [ strings ]
  image: string
  body: [
    { type:  "head" | "para" | "quote" | "image" | "code" ,
      value: string   }]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This roughly represents the schema for a single blog entry in our database. To summarize it: in short, we store the author, creation date, title of the blog entry, an image for the cover, and the body of the article. The focus here is the body of the entry which will be an &lt;u&gt;array of individual sections&lt;/u&gt; of the entry. If we are talking about relational representation, this could be thought of as a foreign key to a sections table. This way we will have more flexibility while styling the elements in our frontend as they would already be isolated as headings, images, code blocks, etc. Additionally, we will add styles for text formatting and links using &lt;strong&gt;regular expressions&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tz3zefrcnmn2lmbmvm5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tz3zefrcnmn2lmbmvm5.png" alt="In Theory, This should work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we spent our time in the back, let's think about how this would look on the front. Once the blog is uploaded, it should look typically the same as the one you are reading right now. The part we care about is the editor which will be used for sending post requests to our backend. This is the part where we need to process user's text into a form that our backend will understand. For now, this lays down a simple layout for our create-blog page.&lt;/p&gt;

&lt;p&gt;The text processing needed for turning whatever user enters into our editor should be implemented in the client with some &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions" rel="noopener noreferrer"&gt;regular expressions&lt;/a&gt; magic. This should be the highlight of this project and while other things are important, this is the part that will decide whether the whole idea works or breaks.&lt;/p&gt;

&lt;p&gt;There may be some other smaller concerns like where we plan to store the images for our blog. Here, one option would be to store it right in the database or maybe in the server and the other would be to use a storage service available, for instance, as you might have noticed, sites like &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt; seem to be using either &lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;AWS s3&lt;/a&gt; or &lt;a href="https://cloudinary.com" rel="noopener noreferrer"&gt;cloudinary&lt;/a&gt; for storing images. The latter should be a better option but it largely depends on the scale of our application. A personal blog with very few images should not require a pricey service.&lt;/p&gt;

&lt;p&gt;With that being said, I kept this one less populated with code and more with the general plan. You can tell me if you like the idea or point out if I am missing some key aspects that might start to cause some trouble once I am deep into the project. Or, you can share any of your ideas of how a better route can be taken for what I'm trying to achieve. &lt;/p&gt;

&lt;p&gt;Hopefully, in the next part, we will get deeper into the implementation. We will make use of regular expressions, express, and CSS/Javascript for styling.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>database</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
