<?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: Abdul</title>
    <description>The latest articles on DEV Community by Abdul (@iamabdul).</description>
    <link>https://dev.to/iamabdul</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%2F616726%2F76c1b155-18a2-4754-9edb-bb56d512a36a.jpeg</url>
      <title>DEV Community: Abdul</title>
      <link>https://dev.to/iamabdul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iamabdul"/>
    <language>en</language>
    <item>
      <title>C# tips: DateTime formatting tip</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Wed, 18 Feb 2026 19:43:10 +0000</pubDate>
      <link>https://dev.to/iamabdul/c-tips-datetime-formatting-tip-2oc9</link>
      <guid>https://dev.to/iamabdul/c-tips-datetime-formatting-tip-2oc9</guid>
      <description>&lt;p&gt;If you want to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026/02/18 at 19:36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time.ToString("yyyy/MM/dd 'at' HH:mm")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even input any string you want in the formatting and it will not be changed or affected, as long as you put the single quotes around it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time.ToString("yyyy/MM/dd 'just because 😄' HH:mm")

// Output
2026/02/18 just because 😄 19:36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for tuning in!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>devjournal</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Creating an AI car analyser</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Sun, 15 Feb 2026 22:03:14 +0000</pubDate>
      <link>https://dev.to/iamabdul/creating-a-car-analyser-ai-jj4</link>
      <guid>https://dev.to/iamabdul/creating-a-car-analyser-ai-jj4</guid>
      <description>&lt;p&gt;Hellooo, I've become interested in creating, and this is one of the things I've been looking into. The car market is a weird, some may argue under-regulated market, and I've been thinking about how a new comer like me can be protected. It will be a part of a series of ideas and their architectural aspects. Hope you enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why am I doing this?
&lt;/h2&gt;

&lt;p&gt;I've been looking at cars to buy lately, and I've been interested in knowing how I can save myself some time when looking at the details of each car. It's a bore to go from one place to the next and do endless scrolling to get the information that I want. Plus, I need to know how to analyse what I see when I look at the results from certain cars' MOT results. &lt;/p&gt;

&lt;h2&gt;
  
  
  Where do I get the information from?
&lt;/h2&gt;

&lt;p&gt;I thought about looking at where some of the vehicle inspection apps get their information from. Turns out that the information comes form the government, it was a free API! I love free stuff, especially API's, so this was a welcome find. There were many types, and it was fun to see what information you can get from a single licence plate.&lt;/p&gt;

&lt;h2&gt;
  
  
  So that's the information, what do I want to do with it?
&lt;/h2&gt;

&lt;p&gt;I want to use it to feed an AI model, that will be able to analyse the information and get back to me (the user) with well thought, digestible information. Kind of like a buddy car specialist, I'm sure there's some car specialist Models out there, or in the least, the general GPT models have consumed some car content from the internet in the last 10 years.&lt;/p&gt;

&lt;p&gt;This would allow the user to understand, especially if they are not as knowledgeable in cars, the condition of the car, the history of it and how it would affect them if they were to buy it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, where do I start? Draw draw draw 🖼️🎨🖌️
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5u44fpkw8j6pkcolhar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5u44fpkw8j6pkcolhar.png" alt="Plan" width="800" height="1016"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to go with a weird hybrid between flowchart and use case diagram lol. Essentially it should explain the process where the user would enter a licence plate number, it would transfer from the front end to the backend. The backend would check if the licence plate has been requested already by the same or other user, this saves us the money and time it would take calling the AI model API and free data API some rate limits.&lt;/p&gt;

&lt;p&gt;Let's assume it's a cache miss, it would then begin the process of gathering all the data needed by querying the API with the licence plate. After that, we would begin the process structuring the data into a singular object model, called the vehicle analysis object (for a lack of better term, I know 🙄, will change at some point).&lt;/p&gt;

&lt;p&gt;Once that is done, the fun begins, where we serialise the data into a JSON format, that can easily be inserted into a formatted string. The reason we do this is to be able to add it to the prompt we would like to give to the AI model. Of course, the prompt itself will be very concise but will have enough detail to ensure the AI model knows exactly what it needs to do, doesn't waste any output tokens (for those that know that AI models these days talk garbaage for days and waste tokens). The output will 100% have to be in a JSON format that we can quickly deserialise from and use right away. No point in doing extra work if the AI model API doesn't charge by compute but by tokens, so I might as well make them do it!&lt;/p&gt;

&lt;p&gt;Anyway, we can see the weird result circle, which represents...tada.. the result, which we will then use as part of an action to ensure that result is transformed into a more front end friendly object. This will save to the cache, with a specific cache expiry lifetime. I haven't decided yet what the cache lifetime could/should be, but my gut feeling while looking at cars in some of the websites, that good cars can go pretty quickly, maybe like in 1-2 days. This probably means I wouldn't be the only one looking at them, but I don't want to hold things for a whole 2 days just in case people are interested, I'd clog up the RAM! Instead, I'll be starting with 6 hour cache potentially and see where it goes from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side notes
&lt;/h2&gt;

&lt;p&gt;An interesting thing I thought of was the issue of the cache itself, and the way in which I can find out how long should the expiry be. There would be monitoring involved of course, more so looking at how the all the request that go to any of the free data API, as the query will just be the licence plate, so it'd be easy to search.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's all for now
&lt;/h2&gt;

&lt;p&gt;I guess for now I'm just going through the creation of the app, starting with exploring the APIs and their documentation. It should give me a vision on how to structure the code, and how to model the vehicle analysis object. Thanks for tuning in, see you in the next instalment! 🙌&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Parallel vs Concurrent ✌☝</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Thu, 18 Jul 2024 07:56:58 +0000</pubDate>
      <link>https://dev.to/iamabdul/parallel-vs-concurrent-mm5</link>
      <guid>https://dev.to/iamabdul/parallel-vs-concurrent-mm5</guid>
      <description>&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;Hello, just small notes to myself on the definitions of Parallel vs Concurrent programming. Hope it helps differentiate the meanings into distinct mental boxes for you 🤙&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallelism
&lt;/h3&gt;

&lt;p&gt;This is where a program executes multiple tasks at once, literally, through different threads. And so, as a result, the tasks execute at the same time.&lt;/p&gt;

&lt;p&gt;Parallelism usually requires some sort of hardware support. For example, when running a program in parallel, there would usually be two or more cores helping tasks to run at the same time with no dependency on each other. If there was a dependency in one task on the other, then it would be more difficult to assume Parallelism as you'd have to wait for one task to finish it's par to start the other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency
&lt;/h3&gt;

&lt;p&gt;Concurrency in it's literal definition means the same thing as parallelism, looking at the oxford definition:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;the fact of two or more events or circumstances happening or existing at the same time&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It feels like there's two definitions of this term among many developers, and the other term is more specific in that it executes task differently than Parallelism does. According to a post on Stack Overflow (the ocean of knowledge that helps us keep our jobs everyday 😄):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Concurrency is when the execution of multiple tasks is interleaved, instead of each task being executed sequentially one after another.&lt;/em&gt; - &lt;a href="https://stackoverflow.com/questions/4844637/what-is-the-difference-between-concurrency-parallelism-and-asynchronous-methods#:~:text=Concurrency%20is%20when%20the%20execution%20of%20multiple%20tasks%20is%20interleaved%2C%20instead%20of%20each%20task%20being%20executed%20sequentially%20one%20after%20another." rel="noopener noreferrer"&gt;link to post here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, instead of doing everything at the same time, tasks are executed interchangeably; when one task is halted and waiting for something, the thread can go somewhere else and tackle a different task. In terms of hardware support, a thread executing instructions would typically only execute one instruction at a time, but can interchange between instructions so fast that it looks like it's doing it at the same time.&lt;/p&gt;

&lt;p&gt;A note to remember is that parallelism is a term that lives inside the broader concept of concurrency, because they both share the definition of simultaneous executions. The more specific definition of concurrency, however, does not equate to parallelism because of what we just mentioned.&lt;/p&gt;

&lt;p&gt;Please feel free to correct me on the definitions if you see something incorrect, would be much appreciated! 🙌&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Re-learning security: detecting package vulnerabilities 🎁 NPM and Nuget.</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Wed, 24 Jan 2024 16:15:43 +0000</pubDate>
      <link>https://dev.to/iamabdul/re-learning-security-detecting-package-vulnerabilities-npm-and-nuget-5clp</link>
      <guid>https://dev.to/iamabdul/re-learning-security-detecting-package-vulnerabilities-npm-and-nuget-5clp</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hello, and welcome to today's post on detecting third party package vulnerabilities in the .NET and JavaScript space. &lt;br&gt;
In this post, we delve into the realm of package vulnerabilities, exploring. We also take a look at how the .NET and JavaScript leverage tools to address these vulnerabilities. What does Github have to do with all of this, and how can I get started on detecting dependency vulnerabilities today?&lt;/p&gt;

&lt;h2&gt;
  
  
  Vulnerable?
&lt;/h2&gt;

&lt;p&gt;To define a vulnerable dependency, lets look at the word &lt;em&gt;vulnerable&lt;/em&gt; in the app security context. &lt;/p&gt;

&lt;p&gt;The OWASP website states that &lt;em&gt;a vulnerability is a hole or a weakness in the application, which can be a design flaw or an implementation bug, that allows an attacker to cause harm to the stakeholders of an application.&lt;/em&gt; (&lt;a href="https://owasp.org/www-community/vulnerabilities/#:~:text=What%20is%20a%20vulnerability%3F" rel="noopener noreferrer"&gt;Link here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Pretty straight forward, to be fair. So for our situation, there's code out there in third party packages that are made in a way which can be exploited by either the author or other attackers who are accessing the application which uses that package.&lt;/p&gt;

&lt;p&gt;I like the phrase shared in "Alice and Bob Learn Application Security" regarding assessing the security of third party applications: "&lt;em&gt;if it is insecure, your application is now also insecure&lt;/em&gt;".&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of vulnerabilities
&lt;/h2&gt;

&lt;p&gt;Much like the love that parents show their children, not all vulnerabilities are equal (did I share too much?😐). There are two main types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Known&lt;/li&gt;
&lt;li&gt;Unknown&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Known vulnerabilities
&lt;/h3&gt;

&lt;p&gt;Consider a situation where you have decided to install an open source application in your computer. In this situation, you may be fully confident that you wouldn't need to be worried about  any potential security issue that may arise because it's "public" for everyone to see, and any code written could be immediately detected and reverted. &lt;/p&gt;

&lt;p&gt;You're half right, but what about it's third party dependencies? This is where the concept of the known vulnerability comes in. It's a type of vulnerability that is known by the public, an example in this situation is an open source code that has dependencies with known ways of hacking it. Going back to the Alice and Bob book, the open source app is now hack-able too.&lt;/p&gt;

&lt;p&gt;Other examples could include things like an exposed storage account that allows anonymous reads and writes when it's not supposed to, or an api missing authentication/authorization controls. Examples taken from this excerpt &lt;a href="https://apiiro.com/blog/where-cloud-native-application-security-mistakes-are-made-known-vs-unknown-vulnerabilities/#:~:text=Known%20security%20issues%20are%20simple.%20They%20include%3A" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unknown/Unique vulnerabilities
&lt;/h3&gt;

&lt;p&gt;The opposite case comes in the form of software that is "custom" and potentially not "exposed to the public" in a sense. The word "custom" in this case bares the meaning of being containing unique enough code that makes vulnerability discovery all the more of an effort; as opposed to already discovered ones by the public.&lt;/p&gt;

&lt;p&gt;An example of this would include a situation where the company person A works for has unknowingly released vulnerable code. Given the unlucky times companies find themselves in, they happen to run into an attacker with a specific set of hacking skills that are exactly in the area that vulnerability is "suited" for. And so, they discover the unique way to expose this vulnerability from the application and start wreaking havoc.&lt;/p&gt;

&lt;p&gt;In this particular segment, since the main subject is about securing third party dependencies, we'll be talking mostly about known vulnerabilities and how to avoid them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;p&gt;We'll be looking at detecting and avoiding known vulnerabilities in third party dependencies in two languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSharp&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both use very similar ways of detecting third party package vulnerabilities, and are also able to utilize very well known tools the same way. As a result, each section of best practice will mention how it's done for both the .NET framework and JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nuget - CSharp
&lt;/h3&gt;

&lt;p&gt;For those not in the .NET space, Nuget is a development tool that is used by developers to package, publish and consume code in the public sphere. It's also a software used to keep a track of what your project has installed, what needs updating etc.&lt;/p&gt;

&lt;p&gt;In regards to tackling this issue within the .NET space, it's safe to say that this third party dependency management software is the main area we will focus on. As of this moment, the current GitHub Advisory Database shows that there are currently &lt;a href="https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anuget" rel="noopener noreferrer"&gt;560 security issues detected within certain third party packages published to Nuget&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Having this information is vital, in that it allows us to know what packages and versions of those packages are currently dangerous to use, or roll back/forward from in some unavoidable situations. This is good news, but how exactly do we take advantage of this in Nuget?&lt;/p&gt;

&lt;p&gt;Luckily for us we, Nuget already has this feature built into it's software. As pointed out by Drew Gillies in &lt;a href="https://devblogs.microsoft.com/nuget/how-to-scan-nuget-packages-for-security-vulnerabilities/#:~:text=directly%20from%20the%20centralized%20GitHub%20Advisory%20Database" rel="noopener noreferrer"&gt;this post&lt;/a&gt;, Nuget get's it's info directly from Github. So there's less chance of the package information being out of date or incorrect.&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%2Finw5ni3z9d1n2gd60iyj.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%2Finw5ni3z9d1n2gd60iyj.png" alt="Nuget Vulnerabilities shown in the tool box in VS"&gt;&lt;/a&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%2F2y3c6i70j6gl0uxjyfe2.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%2F2y3c6i70j6gl0uxjyfe2.png" alt="Including transitive dependencies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, you may also be a terminal type of person, and that can also be addressed through the use of .NET CLI.&lt;/p&gt;

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

dotnet list package --vulnerable ---include-transitive


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

&lt;/div&gt;

&lt;p&gt;This get's your direct packages, as well as your packages' dependencies. This way, you can see exactly which package needs to be upgraded.&lt;/p&gt;

&lt;h3&gt;
  
  
  NPM - JavaScript
&lt;/h3&gt;

&lt;p&gt;Now, for those that are not in the JavaScript space, NPM stands for Node Package Manager. It's essentially what Nuget is for the .NET space; a public library registry for JS based packaged code.&lt;/p&gt;

&lt;p&gt;Just like Nuget, NPM also uses the Github Advisory Database to power it's reports and package vulnerability detection. It used to have it's very own NPM advisory database, however it later it began solely relying on Githubs version (&lt;a href="https://github.blog/2021-10-07-github-advisory-database-now-powers-npm-audit/" rel="noopener noreferrer"&gt;Circa 2021&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The process is pretty much the same for javascript users in that they can simply run the &lt;code&gt;npm audit&lt;/code&gt; command. This will generate a report of any known vulnerabilities within your dependencies list. This includes &lt;a href="https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities#running-a-security-audit-with-npm-audit" rel="noopener noreferrer"&gt;direct dependencies, devDependencies, bundledDependencies, and optionalDependencies, but does not check peerDependencies.&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's no need to run this separately from &lt;code&gt;npm install&lt;/code&gt;, as part of the &lt;code&gt;npm install&lt;/code&gt; process also runs this audit command. Two for the price of one!&lt;/p&gt;

&lt;h3&gt;
  
  
  While in GitHub
&lt;/h3&gt;

&lt;p&gt;You can also automatically get GitHub to check for any list of dependencies at risk. This can be done via turning on the Dependabot option in the settings of your GitHub repo.&lt;/p&gt;

&lt;p&gt;It's a fairly simple process that can be &lt;a href="https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide" rel="noopener noreferrer"&gt;followed in this example here&lt;/a&gt; if you don't want to have a  no code solution to the issue of detecting vulnerabilities. However if you do, then it can also be done via the use of yaml files, but letting GitHub deal with that is better in my opinion; less need for us to waste time on it and more time working on our app.&lt;/p&gt;

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

&lt;p&gt;This is what this post is all about, we managed to take a look at the concept of package vulnerabilities and the different ways it presents itself; being known or unknown. We've also seen how both the .NET and JavaScript worlds use certain tools to deal with these vulnerabilities. Both of which are tied to a very popular GitHub Advisory Database which keeps track of all the &lt;code&gt;known&lt;/code&gt; vulnerabilities, and can automatically scan/reports on our app dependency vulnerabilities so we don't have to. &lt;/p&gt;

&lt;p&gt;I hope you enjoyed and learned from this post, I know I did 🙌 Until next time, in the next post and in the next learning opportunity 👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>dotnet</category>
      <category>security</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Re-learning security: Encryption, Encoding, Hashing ☄</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Wed, 27 Dec 2023 19:57:34 +0000</pubDate>
      <link>https://dev.to/iamabdul/re-learning-security-encryption-encoding-hashing-1d1m</link>
      <guid>https://dev.to/iamabdul/re-learning-security-encryption-encoding-hashing-1d1m</guid>
      <description>&lt;p&gt;Helloo peeps, hope all of our holidays have been well and we all stayed healthy, positive and ready to change the world (and ourselves) for the better in this winter 🙌❄. Today we will be exploring some key &lt;em&gt;word jumbling&lt;/em&gt; processes that differ in definition, processes and intentions. Hope you enjoy, as always I would appreciate a nudge if there's anything that needs correction!&lt;/p&gt;

&lt;h2&gt;
  
  
  Encoding
&lt;/h2&gt;

&lt;p&gt;Encoding, &lt;a href="https://owasp.org/www-project-proactive-controls/v3/en/c4-encode-escape-data#:~:text=(commonly%20called%20%E2%80%9COutput%20Encoding%E2%80%9D)"&gt;or output encoding as the OWASP website mentioned it's commonly called&lt;/a&gt;, is essentially the transformation from one format to another specific format that is understood by a target you wish to send it to.&lt;/p&gt;

&lt;p&gt;It's a sort of translation between languages. Typing a quick google search of "Types of encoding in programming", I can see that there are many, some of which is more common; Like URL encoding, HTML encoding and Base 64 encoding among others. You can also count the transformation of human readable code into 1's and 0's as encoding, because now the machine understands what we're trying to do with that code.&lt;/p&gt;

&lt;p&gt;The purpose for this, as greatly put in the "Alice and Bob learn Security" book, is not to protect the data, but to change the format of the data to be used by wherever you want it to be used. From a security standpoint, the translated characters into that specific interpreter would also no longer possess any power to influence it.&lt;/p&gt;

&lt;p&gt;In keeping with the security theme in this definition, encoding usually goes hand in hand with another popular term called "escaping". It is defined as a way to render a string input by a user as only a string, avoiding the possibility of inputting executable code. An example of this is when we use the backslash (&lt;code&gt;\&lt;/code&gt;) for line breaks and quotes etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of attack and how this technique defends against it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A web app that uses user input in the URL as parameters&lt;/li&gt;
&lt;li&gt;An attacker can use this feature to input a potential redirect to a malicious site which is exactly identical&lt;/li&gt;
&lt;li&gt;Victim is fooled, and evil wins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;As encoding is about making data as easy to understand as possible, encryption is about making it as hard to understand as possible. This is because the point of encryption is to protect the data (the Confidentiality part of the CIA).&lt;/p&gt;

&lt;p&gt;The word "Encryption" is actually part of a larger concept called "Cryptography". Coined as the science of obfuscating data, with the intention of only displaying meaning to anyone with the key to clarifying it. It's a process that's been used for thousands of years (&lt;a href="https://cloud.google.com/learn/what-is-encryption#:~:text=One%20early%20example%20of%20a%20simple%20encryption%20is%20the%20%E2%80%9CCaesar%20cipher%2C%E2%80%9D"&gt;example of the Caesar cipher by google&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Side note: Can we count certain emojis as a sort of encoding 🔥? Because anyone who doesn't know the context won't understand the other meaning behind it. I mean, the ancient Egyptians had emojis for days and it took us a while to decrypt it 👀&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Encryption is the first part of the process, where we make the information no longer understandable. It's a two-way process so it can be "Decrypted" as well (made understandable again). It's true that encoding is technically two way as well, but the difference, at least from my perspective, is that encryption involves secret keys to get the actual value from the jumbled up words.&lt;/p&gt;

&lt;p&gt;There are two types of encryption (ways to make the jumbled up words), one is more secure than the other so we'll go through them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric encryption&lt;/li&gt;
&lt;li&gt;Asymmetric encryption&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Symmetric encryption
&lt;/h3&gt;

&lt;p&gt;From the first word "Symmetric" we can tell that there is an equal "something" on both sides, and that thing is the key used to encrypt and decrypt the information. It's known as the shared key or private key and if someone were to get a hold of that, they would be able to both encrypt and decrypt valuable information. A con to this is that it's seen as the less secure out of the two types, but a pro is that it's cheap to execute and doesn't take much compute power.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asymmetric encryption
&lt;/h3&gt;

&lt;p&gt;Opposite to the previous type of encryption, this one has an inequality between encryption and decryption. And, you guessed it, the keys are different when doing either action. As google simply puts it "One is a public key shared among all parties for encryption. Anyone with the public key can then send an encrypted message, but only the holders of the second, private key can decrypt the message.". This, being the opposite, is seen as more secure, but takes more compute power because of the size of the public key (being stupidly large). It makes sense, then, for google to suggest that "asymmetric encryption is often not suited for large packets of data.".&lt;/p&gt;

&lt;h2&gt;
  
  
  Hashing
&lt;/h2&gt;

&lt;p&gt;Going back to comparing the two-way system of encryption and encoding, hashing on the other hand is one way. This means that once it's jumbled up, that baby is gone and will not be understood again. You might think "that's a bit extreme" at first, and I thought that too. This was until I took myself outside of the box where the hashed values live, to see what the intention is.&lt;/p&gt;

&lt;p&gt;First, though, let's take a step back and look at some concrete ways to define what hashing is. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;TLDR: It's basically a unique fingerprint of the data that's created using that very same data, via an algorithm&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;A hashing algorithm transforms blocks of data that a file consists of into shorter values of fixed length. In other words, a hash value is basically a summary of what is in that file.&lt;/em&gt; - &lt;a href="https://ctemplar.com/hashing-algorithm/#:~:text=A%20hashing%20algorithm%20transforms%20blocks%20of%20data%20that%20a%20file%20consists%20of%20into%20shorter%20values%20of%20fixed%20length.%20In%20other%20words%2C%20a%20hash%20value%20is%20basically%20a%20summary%20of%20what%20is%20in%20that%20file."&gt;crypto templar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Hashing is the process of converting data — text, numbers, files, or anything, really — into a fixed-length string of letters and numbers. Data is converted into these fixed-length strings, or hash values, by using a special algorithm called a hash function.&lt;/em&gt; - &lt;a href="https://www.codecademy.com/resources/blog/what-is-hashing/#:~:text=Code%20with%20Blockly-,What%20is%20hashing%3F,-Hashing%20is%20the"&gt;codecademy&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what is the intention? Well, it seems from the get go that jumbling up this data may mean we want to hide it. However, according to Tanya Janca's "Alice and Bob learn security", she claps back at that idea saying that &lt;em&gt;"data is not the value; proving your identity is"&lt;/em&gt;. This makes sense since it's a one way jumbling process, if someone were to get it they wouldn't be able to use it anywhere. They can't take it back to the application and try enter it as a password, because the system will try and hash that hash and compare it with the hashed password in it's system (too many hashes, say it all again but quickly 🙄🧻💩).&lt;/p&gt;

&lt;h4&gt;
  
  
  The security issue of hashing and it's variations
&lt;/h4&gt;

&lt;p&gt;Let's go into that scenario and pretend that someone gets the hashed version of that password, something like &lt;code&gt;dfli458tv5oyo84ht4ti45ut45&lt;/code&gt;. You would think that the damage is minimized by jumbling up the password, so they would find it near impossible to find the real value. Well, we'd be kind of wrong but not all the way.&lt;/p&gt;

&lt;p&gt;To explain this further, we have to acknowledge the amount of hashing algorithms out there; starting with one of the earlier, probably commonly known, MD5 hashing algorithm. Created in the early 90s, it's aim was just as mentioned: jumble up words so that it's no longer usable, and it was used in a lot of places in systems for years. Until at some point technology and computing minds improved, and it exposed some pretty serious flaws in it. I was able to understand the list of vulnerabilities simpler &lt;a href="https://medium.com/@techclaw/exploring-the-power-and-vulnerabilities-of-the-md5-algorithm-feb249ef9dfb#:~:text=Vulnerabilities%20of%20MD5"&gt;in this link&lt;/a&gt;, I will list a couple of them here anyway:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collision Vulnerabilities : There's a chance that two different values can produce the same hash 😱 now imagine a bot that tries to create any value to match the hash, and it can run locally until it finds one.&lt;/li&gt;
&lt;li&gt;Preimage Attacks : It can apparently be reverse engineered, I did a shallow search to see if that is possible but I only got ideas for Collision attacks (first vulnerability).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since MD5, however, there came more secure and now widely used hashing algorithms to last us for the moment. Some include SHA-256 and SHA-3. These alternatives provide better security against the attacks mentioned. But, oh boy 🤦‍♂️, we will eventually have to worry about quantum computing which is so powerful that there is a chance that some of the strong hashing algorithms today can be pushed aside. Apparently some of the SHA hashing family of algo's are &lt;em&gt;quantum safe 🙃&lt;/em&gt; from collisions and preimage attacks, and it's a long way from now so I can relax a little for the next &lt;em&gt;n+&lt;/em&gt; years lol.&lt;/p&gt;

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

&lt;p&gt;So we learned a few things today about the different ways we jumble words up for security reason. We learnt that encoding is not actually made to protect, but to actually make it more readable to it's data's target - Encoding (i.e humans understand words, machines understand 1's and 0s). Unlike encoding, encryption values the data and does not want to even be found. So it uses different (secretive) styles of keys to jumble the data, so that any party with the key unlock it and get what they need. The last is hashing, which is one-way and doesn't care who sees the jumbled up value or not. We learnt that there are some vulnerable hashing algorithms out there, but just as current ones are being exposed everyday, newer and stronger ones pop up at a similar rate too.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed and learned form this post, I know I learnt a lot from it myself! Thank you for sticking around, as always please comment let me know of any good or bad, I wanna be better!&lt;/p&gt;

&lt;p&gt;See you in the next post 👋&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>devjournal</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Underrated concepts in C#: Delegates and Events</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Wed, 20 Dec 2023 14:53:46 +0000</pubDate>
      <link>https://dev.to/iamabdul/underrated-concepts-in-c-delegates-and-events-3o99</link>
      <guid>https://dev.to/iamabdul/underrated-concepts-in-c-delegates-and-events-3o99</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hello and welcome to another blog post, about something that I either didn't know or didn't fully understand (and somehow got away with in my career 😆). In this particular post we will be looking into delegates and events, what they are and how they're used.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are delegates and events?
&lt;/h2&gt;

&lt;p&gt;I've used these two C# keywords in applications before and know what they can do what, why it's used for. But for some reason I can't put it into words, my initial thoughts were that it was because I think I didn't understand it correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delegates
&lt;/h3&gt;

&lt;p&gt;According to Microsoft &lt;em&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/events/#delegates"&gt;A delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and it can hold references only to methods that match its signature.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I agree with this statement fully, but to me it makes more sense to think of it as a type the &lt;strong&gt;can&lt;/strong&gt; hold a reference to a method, as well as be used as a type for declaring an event (this will be explored in the next section). Some also see delegates as a contract between the publisher and the subscriber, in that all the events related to a particular topic will be sent with a particular type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v-r6XLpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggg8krj4ecsomw6ptoxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v-r6XLpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggg8krj4ecsomw6ptoxj.png" alt="Example-1" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example above, we can see a few things happening. Firstly, the declaration of the delegate &lt;code&gt;DoSomething&lt;/code&gt; can be seen in line 4. Line 8 shows the assignment of the delegate to a method in line 8. We can also see they're being called in line 9 which produces the &lt;code&gt;Normal text: normal text&lt;/code&gt; console output. We can also see it being overridden in line 11 and called again in line 12 to demonstrate the override successfully. This satisfies the statement that delegates can hold references to other methods.&lt;/p&gt;

&lt;h3&gt;
  
  
  Events
&lt;/h3&gt;

&lt;p&gt;However, what about the other statement I mentioned that delegates can be used as a &lt;strong&gt;type&lt;/strong&gt; when declaring events? Well, we can see it in line 5 where the event named &lt;code&gt;ThresholdReached&lt;/code&gt; is being declared. This ties in with the notion of agreement in contract between decoupled classes, essentially saying that any event in this name will be of this delegate type. But, how do we use this event, what does an event really mean in relation to delegates?&lt;/p&gt;

&lt;p&gt;Lets go back to Microsoft again, to decipher its definition. It has a few definitions in different areas of it's website, but the simplest one I found was: &lt;em&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/"&gt;Events enable a class or object to notify other classes or objects when something of interest occurs. The class that sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called subscribers.&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The statement of allowing a class to notify another class of happenings is true, however I could do the same with just an instance of a delegate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vr8frI2l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xr87vakpfhtviem9s2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vr8frI2l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xr87vakpfhtviem9s2h.png" alt="with event keyword" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The picture above functions the same as the picture below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pC7nPp_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5eescit95ttr45emay9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pC7nPp_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5eescit95ttr45emay9r.png" alt="without event keyword" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;event&lt;/code&gt; keyword technically fits the bill, however the concept of an event doesn't just belong to it on it's own as we can see. On a surface level, it helped me to accept that, for my current understanding, the &lt;code&gt;event&lt;/code&gt; keyword is used for clarity and to restrict external classes from assigning &lt;code&gt;=&lt;/code&gt; their method to it (thereby wiping out other subscribers) rather than adding to it &lt;code&gt;+=&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  So what use is are events and delegates?
&lt;/h3&gt;

&lt;p&gt;One interesting thing about the pictures shared above is that the outputs are displayed in the order that the methods subscribed to the event. This can give us a clue as to how it can be used, we can create a queue of methods that can be called in order.&lt;/p&gt;

&lt;p&gt;A benefit of using delegates is that, not all classes need to know of each other to execute together. For example, a class that holds 5 injected services could instead be replaced by a single delegate that allows external classes to subscribe to it's events. this way, the original class does not need to know any external unrelated classes, and the external classes are responsible for their own subscription.&lt;/p&gt;

&lt;p&gt;I recently found out that we can execute &lt;em&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-using-delegates"&gt;asynchronous programming using delegates&lt;/a&gt;&lt;/em&gt; 👀. I haven't looked into it as deep as I'd like to yet, but from what I can see, the &lt;code&gt;BeginInvoke&lt;/code&gt; method that is available on delegates allows the main thread to continue execution on the main thread. &lt;em&gt;The original thread, which submitted the request, is free to continue executing in parallel with the target method.&lt;/em&gt; This can be useful for time critical operations that require parallel processing like database operations etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  An easier way of using delegates and events
&lt;/h3&gt;

&lt;p&gt;Microsoft has come up with a way to remove the need to go through the steps of creating a delegate and then defining an event using that delegate signature. It's called `EventHandler, which I had no idea it was introduced donkey years ago:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F8qekm78--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k02o97c1dut8ygq4o18y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F8qekm78--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k02o97c1dut8ygq4o18y.png" alt="Versions where it was available" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;EventHandler&lt;/code&gt; is actually &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.eventhandler?view=net-8.0#:~:text=public%20delegate%20void%20EventHandler(object%3F%20sender%2C%20EventArgs%20e)%3B"&gt;a delegate itself&lt;/a&gt;, with a more or less common scenario signature, in that it allows the subscriber of the event to know who sent it (the first argument in the signature - the sender/publisher) and what arguments to expect (the second argument - EventArgs). This is what declaring it looks like as opposed to the initial way mentioned: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5rahWn_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7l6dqf9kyfrbac5gadr3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5rahWn_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7l6dqf9kyfrbac5gadr3.png" alt="Delegate and event equals EventHandler" width="765" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mind you, this applies the same things as I mentioned in regards to the &lt;code&gt;event&lt;/code&gt; keyword, since it's a delegate as well. So having or not having the keyword would not make much of a difference still.&lt;/p&gt;

&lt;p&gt;Event handlers can be genericised as well, to accommodate for any arguments that he sender may want to send to their subscribers. This can be done through inheriting from the simple &lt;code&gt;EventArgs&lt;/code&gt; class and adding our own properties to it, more on it &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.eventargs?view=net-8.0"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---LE2Exle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjkurz42jga4bgl9ka87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---LE2Exle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjkurz42jga4bgl9ka87.png" alt="Inheriting from EventArgs" width="610" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This class is then used as a generic type for the event handler, which informs it that the receivers of the message will be expecting an object of certain type with certain properties (i.e expecting the ShoeSize property to be present when handling the event).&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra notes
&lt;/h3&gt;

&lt;p&gt;I used to see a check for null before invoking the handlers and I never knew why that was done. It turns out that handlers that have no subscribers are essentially null references. This makes sense because when we're declaring these event handlers, more often than not, we don't actually assign it on the spot. We either add subscribers to it or assign a function to it later or (with the &lt;code&gt;=&lt;/code&gt; sign). I tested this and tried to invoke a "subscriber-less" event handler and sure enough got a null reference exception.&lt;/p&gt;

&lt;p&gt;But what about when we initialise it? Looks like that doesn't have any problems, since it has a subscriber at it inception:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KECK-Q_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hw5ztbz4dje3h24jxjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KECK-Q_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hw5ztbz4dje3h24jxjj.png" alt="First fan" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we've learnt about delegates, events and event handlers, how to use them, when to use them and some small general notes on it. I hope you've learnt something as I did. If I made any mistakes please let me know I would love to keep track of it and make changes so I do not lead people astray. Let's keep learning and falling in love with our craft, much love! 🙌&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Re-learning security: CIA</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Tue, 05 Dec 2023 20:04:15 +0000</pubDate>
      <link>https://dev.to/iamabdul/re-learning-security-cia-4ifh</link>
      <guid>https://dev.to/iamabdul/re-learning-security-cia-4ifh</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hello Hello, been a while since I last posted, but it was for a good reason! I've enjoyed a new company/apartment/life and needed as much time as I could to get situated 🙌 Since then I've learnt a lot, but somehow, also learnt that I have much more to learn 😄 oh the ocean of knowledge, how can I swim?&lt;/p&gt;

&lt;p&gt;For this blog we're going to look into one of the things I've realised I've not paid attention to in the past year or so. As a result, I've gotten rusty, and so I'll be taking a more active approach by addressing it through reading books, doing certain exercises and seeing how I can influence the team I'm apart of.&lt;/p&gt;

&lt;p&gt;A particular reference I'll be reading from as I go through this journey is the "Alice and Bob Learn Security" book. The flow of the blogs will also similar to the structure of the book, as it helps me stick things in my mind easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why start now?
&lt;/h3&gt;

&lt;p&gt;Well, security is, and should always be, one of the first things that should pop into anyone's mind when they're dealing with creating/developing interactive software. Even if it weren't interactive, we'd still need to make sure that our applications are safe and we don't get hurt in the process of making a positive change in the world (one release at a time).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Security Mandate: CIA
&lt;/h3&gt;

&lt;p&gt;This is where the security standard such as the CIA (Confidentiality, Integrity and Availability) is discussed. As it equips us with the ability to make design/code decisions that ultimately help make our apps safer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ub0SWeSA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9tv24qghnx4361uzp3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ub0SWeSA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9tv24qghnx4361uzp3k.png" alt="CIA" width="719" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Confidentiality
&lt;/h4&gt;

&lt;p&gt;Being able to keep information private is harder than first thought, speaking for myself. It also varies in importance depending on the situation. I'm currently reading "Alice and Bob Learn Application Security", and it talks about how confidentiality plays a certain role in their lives. Due to her position as CEO of a top 500 company, Alice does not want certain information about her health to be public (so it's of utmost importance), while Bob (who has a much lower ranking job) doesn't gain or lose anything by letting people know about his heart condition and using a pacemaker.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integrity
&lt;/h4&gt;

&lt;p&gt;For this principle, it's about the accuracy and the currency of the information that is presented to us. The importance which we place this is also something that is dependent on the situation. In trading, for example, we cannot have numbers that are very inaccurate, as this could potentially cause miss-trades: leading to large financial loss in the process. In most cases, I would think, accuracy is part of what is being part for in most, if not all, applications on the internet. However, you could argue that blogs like this don't prioritise this principle as much since it's users can post anything they want (as inaccurate as they want).&lt;/p&gt;

&lt;h4&gt;
  
  
  Availability
&lt;/h4&gt;

&lt;p&gt;For certain applications in the health industry, this could be a case of life and death, literally! Take the previous case of Alice and Bob for example, both of which rely on the availability of their information. Alice, being a diabetic, measures her levels multiple times a day using this device, but she can also do it manually. So having this device not working is not the end of the world for her. However, for Bob, who relies on a pacemaker to keep a consistent rhythm of beats for him: it would be frightening to not have it available and working to help through the irregular heartbeats.&lt;/p&gt;

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

&lt;p&gt;As we read the "Alice and Bob Learn Security" book, we've take a look at these starting blocks, and the why's, of some of the security rules we may see in our everyday applications. Understanding the reason for their existence and how they fit in our lives through the lens of the CIA principles would equip us to make better decisions in the future.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devjournal</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🤹‍♂️ What the heck is caching? 🚶‍♀️</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Fri, 06 May 2022 21:10:21 +0000</pubDate>
      <link>https://dev.to/iamabdul/what-the-heck-is-caching-gb5</link>
      <guid>https://dev.to/iamabdul/what-the-heck-is-caching-gb5</guid>
      <description>&lt;p&gt;Having things in our pockets while we're out are usual, and so is having cached data while we're running our apps 🚶‍♀️🚶‍♂️💽💻&lt;/p&gt;

&lt;p&gt;While resisting the urge to shout "Cache me outside.. how boww daah" at the screen, allow me to explain to you what caching is to me. I will also mention the different types that you can come across and their pros and cons. This is purely from my perspective, it also carries a couple of tips on how to start caching in .NET.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;Caching is the action to store data the first time around you get it, and when it is required again, instead of going to the source (where you got it from), you can go to a much closer place (where you stored it) and retrieve it there instead. This, therefore, saves you time and money.&lt;/p&gt;

&lt;p&gt;..Or as Microsoft puts it: “Caching enables you to store data in memory for rapid access. When the data is accessed again, applications can get the data from the cache instead of retrieving it from the original source.” - &lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/performance/caching-in-net-framework-applications"&gt;Caching in .NET framework applications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my own head, I always see it as a thing you have in your pocket until someone asks for it again, meanwhile you can walk and go about your daily life while this "thing" lives in your pocket until it's needed again.&lt;/p&gt;

&lt;h2&gt;
  
  
  It can be good for ya:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Improves performances and scalability (don’t need to hammer the source that much) &lt;/li&gt;
&lt;li&gt;Can make data available when the source is unavailable &lt;/li&gt;
&lt;li&gt;“Caching works best with data that changes infrequently and is expensive to generate” - &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-5.0#:~:text=.%20Caching%20works%20best%20with%20data%20that%20changes%20infrequently%20and%20is%20expensive%20to%20generate."&gt;Cache in-memory in asp.net core&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hold your horses
&lt;/h2&gt;

&lt;p&gt;To be frank, not everything is roses and rainbows with what is introduced here. It is always advised that we shouldn't build and test our app to &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-5.0#:~:text=Apps%20should%20be%20written%20and%20tested%20to%20never%20depend%20on%20cached%20data."&gt;"depend on cached data"&lt;/a&gt; ; and rightly so, there could creep up discrepancies between the cached store and the origin very easily, especially if the data we're working with has a tendency to change frequently.&lt;/p&gt;

&lt;p&gt;Also when it comes to in-memory cache, we should expect that the more data we store in memory the lower our performance levels become. Metaphorically speaking, we will find it harder to walk around with our pockets as packed as our wardrobes, something will eventual fall out. This is the same with our RAM storage, something has to give. If we use this caching strategy as a half way house for our DB, then we're in a world of trouble.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of caching
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In-memory (or in-process) caching (Cache stored in the memory of the web server, very simple to implement) &lt;/li&gt;
&lt;li&gt;Distributed caching (Cache shared across multiple servers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main differences between them can be seen in this link &lt;a href="https://dzone.com/articles/process-caching-vs-distributed#:~:text=Following%20are%20some%20considerations%20that%20should%20be%20kept%20in%20mind%20when%20making%20a%20decision."&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The decision to choose which really comes down to the situation, where we consider the size and frequency of the data that's being called upon. Can we afford to get from the a source that is a copy of the original, if so then how do we navigate around the consistency issues between these two sources?&lt;/p&gt;

&lt;h2&gt;
  
  
  My personal opinion
&lt;/h2&gt;

&lt;p&gt;For small applications, in general, it would probably be easier and simpler to use the in-memory caching strategy. This is considering the very likely outcome that there would be a minimal and predictable amount of request made given a particular unit of time. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to use in-memory cache in .NET?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install the “Microsoft.Extensions.Caching.Memory” nuget package &lt;/li&gt;
&lt;li&gt;Initialize the MemoryCache object with an options Accessor argument (I.e., MemoryCacheOptions) &lt;/li&gt;
&lt;li&gt;It would usually follow this pattern of fetching or setting:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!memoryCache.TryGetValue("cachedThingIdOrName", out List&amp;lt;int&amp;gt; data)) 
{
    data = memoryCache.Set("cachedThingIdOrName", await GetLargeDatabaseList(), new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(10)); 
} 

return data; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can also be injected using this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In startup, add this: &lt;code&gt;services.AddMemoryCache()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now in any constructor, you can just inject IMemoryCache and it can be used &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to cache using Redis (local dev)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We can use a docker container to pull down/host the latest image for Redis&lt;/li&gt;
&lt;li&gt;After Redis is up and running, we need to download the &lt;code&gt;microsoft.extensions.caching.stackexchangeredis&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;We would also need to download the &lt;code&gt;Stackexchange.Redis&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;Go to the &lt;code&gt;ConfigureServices&lt;/code&gt; method and add the extension method &lt;code&gt;AddStackExchangeRedisCache&lt;/code&gt; with the following expression settings:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;options.Configuration = Configuration.GetConnectionString("Some connectionstring in you config file")&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This gets the connection string /configuration used to connect to the Redis that is set up.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;options.InstanceName = "RedisCachingApp_(app name)";&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This is just a convvention that can be used to stop any potential mix-up when it comes to inserting a value with the same key across multiple apps. Remember that Redis can be shared across different instances and apps in general, so it can be more likely that key names would be mixed, this isolates whatever is set in this app TO this app.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Inject IDistributedCache into the constructor as normal and use&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An important thing to note is to always use a form of expiration otherwise the data would stay in the cache forever. &lt;code&gt;AbsoluteExpirationRelativeToNow&lt;/code&gt; or &lt;code&gt;AbsoluteExpiration&lt;/code&gt;  or &lt;code&gt;SlidingExpiration&lt;/code&gt; are fine to use.&lt;/p&gt;

&lt;p&gt;Thanks for hanging around, see you on the next one 🙌&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>{{{Do curly braces waste space?}}} 📖📘</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Fri, 04 Feb 2022 22:52:42 +0000</pubDate>
      <link>https://dev.to/iamabdul/do-curly-braces-waste-space-1f31</link>
      <guid>https://dev.to/iamabdul/do-curly-braces-waste-space-1f31</guid>
      <description>&lt;p&gt;While writing an if-statement, have you ever wondered about the conventions of the curly braces that follow it? I mean, put curly braces in, don't put curly braces and the "style guide" section of whatever company we work in that tells us which ones to use. Well, I want to look at it in a more factual way. Does it do anything to the common intermediate language (or formerly just IL I believe) that get's drummed up by C# or another .NET language?&lt;/p&gt;

&lt;p&gt;The plan is to give a short demonstration to provide us with the answer we are looking for, and then we can just go back to our daily lives like nothing happened. Or... we can take this to the belly of the beast (our company slack channels), drop the discussion in there and see what happens 👀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, I'm glued, so what happens when I put curly braces in?
&lt;/h2&gt;

&lt;p&gt;Glad you asked, and I'm gonna waste these extra words to make it look like a complex research was conducted. We can see below a simple bit of code that is an if statement, which when true contains a &lt;code&gt;"hello"&lt;/code&gt; being dumped into the console using the &lt;code&gt;Dump&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Firstly, to give a more detailed view of what happens, let's see the IL code that's spouted out when we don't have curly braces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiklen176yodt5jxbx1sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiklen176yodt5jxbx1sc.png" alt="Without curly braces" width="387" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing special to see here, the top bit is the C# code, and the bottom is the Intermediate Language (IL) version of it. We can tell that some steps are taken before going to &lt;code&gt;IL_0003&lt;/code&gt; which let's us know that there's this string &lt;code&gt;"hello"&lt;/code&gt;; it is then followed by &lt;code&gt;IL_0008&lt;/code&gt; which is the execution of the extension method &lt;code&gt;Dump&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Adding the curly braces changes things interestingly, the step numbers (not sure what the name is) seem to have been altered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n363m33o9avymian9ql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n363m33o9avymian9ql.png" alt="With curly braces" width="443" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There seems to be these extra &lt;code&gt;NOP&lt;/code&gt; steps that are added to the list, thereby changing the chronology of the process. I didn't fully understand it's effect on size or time, but I compared it the only way I know how; by saving the file and right clicking to see if there was any size change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq92qbv3tf07rkfz2f5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq92qbv3tf07rkfz2f5r.png" alt="With curly braces" width="334" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above is with curly braces.... and below is...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykpof7y5dwj9xfjji14r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykpof7y5dwj9xfjji14r.png" alt="Without curly braces" width="332" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mind 🤯 blown ... slightly.&lt;/p&gt;

&lt;p&gt;I don't know what or how or why it does this but it certainly is interesting to see a difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this mean on a wider scale?
&lt;/h2&gt;

&lt;p&gt;I'm not entirely sure, but if we were to extrapolate this into a massive real life project, strip all the unnecessary braces and compare I reckon it could display a nuget package or two worth of size difference...Maybe... &lt;/p&gt;

&lt;p&gt;This definitely raises the question about how efficient we can/should be with our code, and could style differences be detrimental or a positive impact on the code base?&lt;/p&gt;

&lt;p&gt;Anyway, if you drop this in the slack, please don't blame me for sudden invitations to a "match to the death" by your colleagues. Also, most of all, don't try this at home 🦺&lt;/p&gt;

&lt;p&gt;Thank you for sticking around!&lt;/p&gt;

&lt;p&gt;I hope to have more stuff underway as I sort my life out at the moment, there will be a few non-technical things I'd like to talk about this year especially concentrating on mental health. There's one in particular that I think could prove important so please watch out for that 😊 See ya round!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>dotnet</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Running a .NET Twitter bot on Pi: Part 3 – Pi in the sky 🥧👩‍🚀</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Mon, 27 Dec 2021 21:37:22 +0000</pubDate>
      <link>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-3-pi-in-the-sky-39if</link>
      <guid>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-3-pi-in-the-sky-39if</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp"&gt;Part 1 : The bot&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-2-the-rules-endpoints-23in"&gt;Part 2 : The rules&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Heya! The final part of this twitter bot series is here. &lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp"&gt;first part&lt;/a&gt; of this series, we've taken a look at creating a twitter bot in .NET that listens to particular tweets and retweets them. For the &lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-2-the-rules-endpoints-23in"&gt;second part&lt;/a&gt; we created Api endpoints for  it, so it now has the capability to change its tweet stream rules whilst listening at the same time. This final part is where we deploy our twitter bot to the Pi, lets go!&lt;/p&gt;

&lt;p&gt;his is the link to the repo (&lt;a href="https://github.com/Iamabdul/DotNetTwitterBot"&gt;here&lt;/a&gt;). It includes the previous changes as well as what will occur during the course of this blog.&lt;/p&gt;
&lt;h3&gt;
  
  
  Requirements first✋
&lt;/h3&gt;

&lt;p&gt;In order for this to work, we will need a couple of things to have at hand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Raspberry Pi&lt;/li&gt;
&lt;li&gt;Setting up the Pi with SSH (&lt;a href="https://www.youtube.com/watch?v=O8AIuD_QAgE"&gt;link here&lt;/a&gt;)

&lt;ul&gt;
&lt;li&gt;Please take note of the OS chosen during the setup for later&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Docker installed in Pi (&lt;a href="https://pimylifeup.com/raspberry-pi-docker/#:~:text=Installing%20Docker%20to%20the%20Raspberry%20Pi"&gt;link here&lt;/a&gt;)

&lt;ul&gt;
&lt;li&gt;I only followed the "Installing Docker to the Raspberry Pi" and "Testing the Docker Installation on Raspberry Pi" sections&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A docker hub account (&lt;a href="https://hub.docker.com/signup"&gt;link here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Docker desktop (&lt;a href="https://www.docker.com/products/docker-desktop"&gt;link here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;(Optional) Docker VS Code extension (&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker"&gt;link here&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Referring to the video for setting up an SSH for the Pi, her video pretty much applies the same to windows users, if you follow that you should be good to go on your Pi/SSH needs: that’s if you actually need to SSH, if you don’t and are fine with the full OS version then you can go ahead with that too 👍&lt;/p&gt;
&lt;h3&gt;
  
  
  Dockerizing ..⛴
&lt;/h3&gt;

&lt;p&gt;The dockerizing part is really nothing new, it's just adding the dockerfile and a dockerignore to our project as seen in many tutorials. I came across a hiccup when attempting to pull an image for our twitter bot into the Pi but we'll work up to that point.  &lt;/p&gt;

&lt;p&gt;To start off in visual studio, we’ll first need to add the docker support to the project, and that is pretty much straight forward; right clicking the project and scrolling down the options to select the “add docker support” button. VS generates the necessary files for our docker process which are the dockerignore and dockerfile files: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SI1t0dS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfrz1i67sfiq2x6tiixi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SI1t0dS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfrz1i67sfiq2x6tiixi.png" alt="dockerfile" width="638" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This can also be done in VS code, ensuring the docker extension installed, via the command (select the first option): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oKZ8N3Ne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxl2h0483cydgnk8dayl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oKZ8N3Ne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxl2h0483cydgnk8dayl.png" alt="VS Code command" width="880" height="348"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Time to build
&lt;/h4&gt;

&lt;p&gt;Once this is done, we are ready to start the build process and we do this by going to the terminal/cmd and cd-ing into our project directory. Because of the way the dockerfile looks for things, and how it sets up what current directory it looks at; I ensured that I ran the following docker command in the solution directory and not the individual project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t {username}/abtest-image -f TwitterBot/Dockerfile . 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command specifics can be found &lt;a href="https://docs.docker.com/engine/reference/commandline/build/"&gt;here&lt;/a&gt;. This command basically states to &lt;code&gt;create&lt;/code&gt; a docker image named &lt;code&gt;{username}/abtest-image&lt;/code&gt; which is based on the dockerfile located in the &lt;code&gt;TwitterBot&lt;/code&gt; folder. The period at the end of the command is also a necessity as it states that we will execute this command in the current directory that we are in.&lt;/p&gt;

&lt;h4&gt;
  
  
  Time to test run
&lt;/h4&gt;

&lt;p&gt;The previous command should build an image, however it has not been run in a container yet. The command to do so is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -p 8080:80 {username}/abtest-image 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we can see that docker instructs (via &lt;code&gt;docker run&lt;/code&gt;) the &lt;code&gt;{username}/abtest-image&lt;/code&gt; image to run on port &lt;code&gt;8080&lt;/code&gt; (via &lt;code&gt;-p 8080:80&lt;/code&gt;). The port argument shows that the left side of the colon is 8080 while the right side is &lt;code&gt;80&lt;/code&gt;. The left side is what docker exposes to the outside world (the users - us) to appropriately talk to this container. The right side is for communication inside the container itself, something we wouldn’t need to look into too much for this project. &lt;code&gt;--rm&lt;/code&gt; is simply an option to let docker know to remove containers once they have been stopped.&lt;/p&gt;

&lt;p&gt;If we want to run this image in a container in the background and not have it hog the terminal, we can introduce the &lt;code&gt;-d&lt;/code&gt; flag just after the &lt;code&gt;run&lt;/code&gt; keyword in that same command above.&lt;/p&gt;

&lt;h4&gt;
  
  
  The hiccup
&lt;/h4&gt;

&lt;p&gt;Now that we have test run this image in our OS, it’s time we talk about the potential nightmare we could’ve gotten into.&lt;/p&gt;

&lt;p&gt;I ran into the hiccup stemming from after creating the dockerfile as instructed above, which is perfectly fine for what we’re currently running on. This file has various steps that include packaging the app into the image we need, however it relies on a base image to create our image from which causes compatibility issues down the line.&lt;/p&gt;

&lt;p&gt;This is usually the first command in the file and it would probably look like this by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that this command doesn’t get an image which targets the correct OS version that our Pi runs on (remember when we mentioned to keep a note of the OS). This could result in a little mess down the line trying to figure out what this message means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The crux of this states that we need to change that first line mentioned a little, depending on what platform we will be targeting. It looks like the platform is targeting the arm instruction set (based on the error message), but to find out what type our host platform (Pi) is running on, we can use the &lt;code&gt;uname –m&lt;/code&gt; command in the Pi terminal. &lt;/p&gt;

&lt;p&gt;This will give us one of two answers, either &lt;code&gt;aarch64&lt;/code&gt; (which means we’re on 64 bit) or &lt;code&gt;armv7l&lt;/code&gt; (which means we’re on 32 bit). Once we find that, we can go to &lt;a href="https://hub.docker.com/_/microsoft-dotnet-aspnet#:~:text=and%20WCF%20Samples-,Full%20Tag%20Listing,-Linux%20amd64%20Tags"&gt;this link&lt;/a&gt; to find out what version of aspnet in that command we should be pulling down. For my case, it was &lt;code&gt;6.0.1-bullseye-slim-arm32v7&lt;/code&gt; and I’d safely guess it could be yours too:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agOcgHec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejaffdrwtqljip7ikr6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agOcgHec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejaffdrwtqljip7ikr6c.png" alt="Image tag listing" width="880" height="149"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now the command looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mcr.microsoft.com/dotnet/aspnet:6.0.1-bullseye-slim-arm32v7 AS base 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this change, running this image in our current OS wouldn’t work as we’ve changed our target platform, but it will run on the Pi (have faith and stay the course!). Now that we have built up the image, it’s time to fling it off to the web!&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing the image to the hub 🚀
&lt;/h3&gt;

&lt;p&gt;In order for us to publish the image to docker hub we will need to have a docker account. Given the steps mentioned at the start, we can safely assume this has been done already. &lt;/p&gt;

&lt;p&gt;In our current terminal, we will need to log into to our docker hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker login docker.io -u &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A standard credential check will occur, after which we should be granted access to our account via the terminal.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Side note, the “docker.io” part was added to solve an issue I had with pulling from a private repo. I could have used “docker login” on its own and it would have worked for the steps later if I chose to have a public repo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anyway, once we’ve logged in, we can finally get to the juicy part which is pushing this image out there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker push {username}/abtest-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does what it says on the tin. The image we created earlier will now be pushed into a new repo in the cloud with the same name. There might be some problems here as I have experienced, mostly to do with the naming convention of the image name. I found that pushing an image name without my username preceding it was not possible, it gave me errors stating &lt;em&gt;“request to the resource is denied”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I looked at the logs when attempting to push the image with that exact name and it seems to push to a directory that didn’t belong to me (if you know please drop a comment below 👍):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The push refers to repository [docker.io/library/abtest-image]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when I used my docker username and then followed by “/abtest-image”, the logging looked different and the push succeeded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The push refers to repository [docker.io/{username}/abtest-image]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the web to see that the new repo is there and it should be 🙌.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pulling the image from the Pi(moment of truth)
&lt;/h3&gt;

&lt;p&gt;Coolio, we’ll need to SSH in to the Pi for this. When we have done so, we’ll need to install docker into the Pi. &lt;a href="https://pimylifeup.com/raspberry-pi-docker/"&gt;This blog&lt;/a&gt; is adequate enough to install docker, three quick easy steps to get docker into the Pi 👍 &lt;/p&gt;

&lt;p&gt;Once that is done, all that is left is to say these magic words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull {username}/abtest-image 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will do its thing, with regards to getting the image down from our remote repo and adding it to the list of images in our Pi docker. Check using the &lt;code&gt;docker images&lt;/code&gt; for this list. &lt;/p&gt;

&lt;p&gt;Once that is done, and the hiccup issue has been resolved, we should be able to run our twitter bot using the same command in previous steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d -p 8080:80 {username}/abtest-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test it in the Pi for a final time to see if it holds and we should have lift off!&lt;/p&gt;

&lt;p&gt;This was a fun project to take on, this three-part series saw me create a .NET twitter bot app which listens to specific tags I’ve pre-set and retweets those tags. We then went onto creating endpoints to change what the tweet stream should and shouldn’t listen to by exposing the “rules” end point. This led to looking at deploying this .NET bot onto the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;I’ve learnt quite a bit from this, I was able to enjoy some of the features of .NET 6 such as minimal Api. This was also followed by a refreshing and fun exposure to docker and how it can be used. I have some ideas for a bonus episode on how much a dockerized twitter bot in azure would rack up in costs. I have a feeling it wouldn’t be more than two burgers worth a month (let's hope it doesn't cost me a pretty penny!).&lt;/p&gt;

&lt;p&gt;Thank you for sticking around and following my journey with this twitter bot, I hope to see you in the next project I decide to take on. PS: lookout for that possible bonus episode on exploring this bot with Azure 🚀&lt;/p&gt;

</description>
      <category>twitter</category>
      <category>dotnet</category>
      <category>devjournal</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Running a .NET Twitter bot on Pi: Part 2 – The Rules endpoints 🗣🤳</title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Sun, 05 Dec 2021 16:16:51 +0000</pubDate>
      <link>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-2-the-rules-endpoints-23in</link>
      <guid>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-2-the-rules-endpoints-23in</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp"&gt;Part 1 : The bot&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-3-pi-in-the-sky-39if"&gt;Part 3 : The Pi in the sky&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp"&gt;first part&lt;/a&gt; of this series, we've taken a look at creating a twitter bot in .NET that simply listens to particular tweets and retweets them. But we were missing the ability to control what this bot can and cannot listen to. This is the link to the repo (&lt;a href="https://github.com/Iamabdul/DotNetTwitterBot"&gt;here&lt;/a&gt;). It includes the previous changes as well as what will occur during the course of this blog.&lt;/p&gt;

&lt;p&gt;For this part of the project, I’ll be adding the endpoints to the existing TwitterBot project. However, some things need to be chopped and changed about: such as migrating the current project to target *&lt;em&gt;.NET 6 *&lt;/em&gt; (in order to take advantage of minimal Api’s).  Firstly, though, I’ll be exploring what it takes to create the templated Api project in .NET 6.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating the Api project but from scratch
&lt;/h3&gt;

&lt;p&gt;It would have been all well and easy for me to create an Api project from the template, but I wanted to really note what it takes to create an Api project from scratch (especially for a .NET 6 version). I decided to create two projects and compare both, one is a console project which I will be using to create my sample Api project, and another pre-made Api project generated from the VS template. Both of these projects are in .NET 6.&lt;/p&gt;

&lt;p&gt;As I started, I already noted some differences between the standard and the console templates. The first being in the CSProj files, their SDKs are different; the console one is &lt;code&gt;Microsoft.NET.Sdk&lt;/code&gt; while the Api one is &lt;code&gt;Microsoft.NET.Sdk.Web&lt;/code&gt;. This could be where the Program.cs file gets its ability to use the &lt;code&gt;WebApplication&lt;/code&gt; class without any using statement. The second difference is that the console project has an output type property in its CSProj while the Api doesn’t (although it does have the lanchsettings.Json for how it should execute etc).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--64vwPQop--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnmy6da3pebmmoi86rw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--64vwPQop--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnmy6da3pebmmoi86rw4.png" alt="Differences" width="459" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After I amended my CSProj to look like its Api counterpart and built the projects, the references started to look the same also. It seems to have added the Microsoft.AspnetCore.App reference as a result of a change in Sdk.  &lt;/p&gt;

&lt;p&gt;I’ve managed to get the first few lines down in order to get the Api project up and running, only these three lines were really needed in the Program.cs file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args); 

var app = builder.Build(); 

app.Run(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These will be entered in order, and we shouldn’t get any errors as the &lt;code&gt;WebApplication&lt;/code&gt;class relies on the &lt;code&gt;.Web&lt;/code&gt; Sdk we have in the CSProj (as mentioned previously). Just before the third line, we can create an example endpoint that will help us determine the success so far. Use the &lt;code&gt;app&lt;/code&gt;variable to access the &lt;code&gt;MapGet&lt;/code&gt; method, which is essentially a shorter version of creating a HTTPGET endpoint in a controller we’d usually have.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.MapGet("/hey", () =&amp;gt; "Hello World”);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the first argument is the endpoint we’re establishing, the second argument is a function we pass down which will be invoked whenever the endpoint is hit. &lt;/p&gt;

&lt;p&gt;Another cool thing to mention is that the configuration manager works out of the box. All we have to do is access it using the &lt;code&gt;app&lt;/code&gt; variable like so: &lt;code&gt;app.Configuration["Greeting"]&lt;/code&gt;. Try it with the &lt;code&gt;MapGet&lt;/code&gt; method as an endpoint result 👍.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cool, sounds good, time to apply migration to the real project!
&lt;/h3&gt;

&lt;p&gt;Currently we have two projects, a library and a console project that runs a hosted services for listening to these tweets. Leaning on what we’ve learnt in the previous section, we can also turn this into a .NET 6 project and get it up and running. The steps are the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change &lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk"&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk.Web"&amp;gt;&lt;/code&gt; in the CSProj.&lt;/li&gt;
&lt;li&gt;Most of the nuget packages that we use for hosting and configurations (such as &lt;code&gt;.Extensions.Configuration&lt;/code&gt; and &lt;code&gt;.Extensions.Hosting&lt;/code&gt;) will not be needed anymore and can be removed.&lt;/li&gt;
&lt;li&gt;No need to let the CSProj know that we rely on an &lt;code&gt;appSettings.Json&lt;/code&gt; file and that we need it to be copied to output, we can remove this section as well.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What we should have as a result is this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FFWga2nj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fs41rr48vfwchhx8pn98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FFWga2nj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fs41rr48vfwchhx8pn98.png" alt="CSProj result" width="628" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note that I kept the output type to exe as I like a console but you can feel free to delete the &lt;code&gt;OutputType&lt;/code&gt; line. Also, I made sure in the launch settings that the &lt;code&gt;launchBrowser&lt;/code&gt; property is marked as false as I won’t be needing it for now (possible play with blazor stuff soon? 👀) as this is just an Api project with a running background service.&lt;/p&gt;

&lt;p&gt;I also changed the library project into .NET 6, ensuring the &lt;code&gt;OutputType&lt;/code&gt; is Library, changing Sdk type to &lt;code&gt;.web&lt;/code&gt; and, as a result, removing all the unneeded nuget references.&lt;/p&gt;

&lt;p&gt;After the setup I made sure to test that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Any fake endpoint works &lt;/li&gt;
&lt;li&gt;Any &lt;code&gt;appsettings.json&lt;/code&gt; property can be reached using &lt;code&gt;IConfiguration&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cool, migrated the console project into a functioning api project, time to get the rules endpoints down
&lt;/h3&gt;

&lt;p&gt;This was a very quick way to setup endpoints (as shown in the previous section). It work's right out of the box, no routing and none of the faff needed to configure 😍. However, it doesn’t feel like a clean room for me to have all the endpoints just splatted out there in the Program.cs. So, I created an extension method to help with organization. If it’s for a first iteration, it's just as standard to have it in the same page if that is what is preferred.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--usmj_UzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4fxxak9ba3q8zje4rht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--usmj_UzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4fxxak9ba3q8zje4rht.png" alt="1" width="513" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WM4ihPAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7on9t8ll25qk4ggpzki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WM4ihPAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7on9t8ll25qk4ggpzki.png" alt="2" width="880" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflection
&lt;/h3&gt;

&lt;p&gt;It’s correct to assume that it may be too much to separate the Api endpoints from the Program.cs file at this stage as there’s not many. It ended up creating more work for myself in the end while trying to make it look neater. I'm not sure if any of the successful companies ever had the perfect looking code base to begin with, functionality must have come first: and as the code expands it would then be more reasonable to look for ways to optimize the structure. I also feel I’ve done too much, could there have been ego involved in the over engineering aspect? I will reflect on this in another blog 👍&lt;/p&gt;

&lt;p&gt;I was able to create Api endpoints for the twitter bot that also has a running background service to listen to tweets. It now has the capability to change its rules whilst listening. The comparison of a .NET 6 console project and a .NET Api template project helped me in the migration stage for the twitter bot, as well as the library. The &lt;code&gt;.Web&lt;/code&gt; Sdk proved to be very useful in getting rid of all of the junk that’s involved with establishing an Api project. However, one thing I will take a look into in further projects, and on a separate blog, is the effect of over engineering and how ego can play a part in it. &lt;/p&gt;

&lt;p&gt;Please let me know of any mistakes made during this project and/or this blog, it would be very much appreciated! Now that we have this done, time for part 3, which is looking to host this bad boy onto a Pi 4! Thanks for sticking around, see you then! 👋 &lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>twitter</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Running a .NET Twitter bot on Pi: Part 1 – The Bot </title>
      <dc:creator>Abdul</dc:creator>
      <pubDate>Fri, 19 Nov 2021 17:32:37 +0000</pubDate>
      <link>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp</link>
      <guid>https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-1-the-bot-2cdp</guid>
      <description>&lt;p&gt;I know there are a bunch of .NET twitter bots out there, there are even packages such as TweetInvi that can help me pretty much setup a bot straight away. However, I’ve decided to take the hard road on this challenge and do it myself. I'd like to get more in-depth knowledge about what it takes to create a bot, to deploy it and explore possible scenarios that can arise after deployment as a result of the choices made during development.&lt;/p&gt;

&lt;p&gt;This three-part series contains a project that will take a look at creating a .NET app which will listen to specific tags I’ve pre-set and will retweet those tags. After that, we will then go on to creating endpoints for influencing what the stream should and shouldn’t listen to, hitting the “rules” end point for twitter. We will also look at deploying this .NET bot onto my newly purchased Raspberry Pi (the last two objectives will be in no particular order).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-2-the-rules-endpoints-23in"&gt;Part 2 : The rules&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/iamabdul/running-a-net-twitter-bot-on-pi-part-3-pi-in-the-sky-39if"&gt;Part 3 : The Pi in the sky&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting with a console app to test
&lt;/h3&gt;

&lt;p&gt;I wanted to get to grips with how twitter outputs its stream. The most straight forward way for me to get into it was to create a simple console app that has a HttpClient, which consumes whatever comes from the never-ending stream; and that’s what I did! Also by the way, I made a call (outside of the app using postman) to the twitter stream rules endpoint. This is in order to create a rule for my filtered stream to listen to, when providing me with messages (&lt;a href="https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules"&gt;link here&lt;/a&gt;). This is just to get things started until I get to the next episode in the series.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qjMrwGAV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cebdls2e6hqgu50j9jx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qjMrwGAV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cebdls2e6hqgu50j9jx4.png" alt="Simple console app example" width="731" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What happened in that pic, was it WebSockets?
&lt;/h3&gt;

&lt;p&gt;It was the use of HTTP streaming, a method whereby the response to the client is held open by the server with basically no end in sight until the server decides so. If you would like to find out the differences between these two WebSockets and HTTP streaming, check this brief explanation in this blog &lt;a href="https://dev.to/iamabdul/websockets-and-http-streaming-in-net-5k2"&gt;here&lt;/a&gt; and why I chose to go with this rather than WebSockets. &lt;/p&gt;

&lt;p&gt;To sum up that short blog, I’ve taken a look at the twitter Api documentation which states that it delivers “...Tweet objects in JSON format through a persistent HTTP Streaming connection.”. This is what essentially made me choose HTTP Streaming instead for this occasion.&lt;/p&gt;

&lt;h3&gt;
  
  
  We got it working, time to do something with it
&lt;/h3&gt;

&lt;p&gt;After cleaning it up a little, and established being able to create a “listener” to these tweets, we will look creating the action of posting a tweet whenever something pops up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cU4I2V2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyun77ayq3e45izn7b44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cU4I2V2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyun77ayq3e45izn7b44.png" alt="Cleaned up and simplified" width="648" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This new code is the shortened version of the first example, we just separated the responsibilities and placed them in different classes. The &lt;code&gt;TwitterStreamQueries&lt;/code&gt; class (as the name suggests) is responsible for the establishment streams, whether it’s the filtered one (as shown) or any other that could be applied in other scenarios. It takes in a &lt;code&gt;TwitterClient&lt;/code&gt; class that is responsible for instantiating things such as client credentials and base Uri etc. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GetFilteredStream&lt;/code&gt; method is probably the most interesting thing here because we pass in a function as its argument. This is to provide the filtered stream the open-closed opportunity. This in return gives us the flexibility to chop and change the function argument however we like; without much, if any, changes to the &lt;code&gt;GetFilteredStream&lt;/code&gt; method. To start with, I created a function that acknowledges a message for iteration's sake, surprise... it works 👍.&lt;/p&gt;

&lt;p&gt;Time to create a process that will retweet the message that comes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  The retweeting process
&lt;/h3&gt;

&lt;p&gt;As the title suggests, I now dive into what it takes to be able to create a successful retweet request. One thing I do know is that I cannot use the same client, as twitter has a different authorization header requirement for the post request (OAuth1.0 instead of OAuth2.0 which uses bearer tokens). &lt;/p&gt;

&lt;p&gt;There were many ways in which I could have ensured that the client used for a particular process utilizes the correct OAuth header for its intended purpose. An example of this could be creating a separate client for each OAuth process (I.e. OAuth1 client and OAuth2 client). However, that is too much for a single purpose-built app such as this.&lt;/p&gt;

&lt;p&gt;For this particular case, I thought to go with assigning the header required for each case in their own respective method. It’s a simple enough solution that only cares about listening to the stream and retweeting, I won’t faff about with it I reckon 🤷‍♀️ (being a lazy dev here – don't copy me!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lACJBDW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwaatwlr93rnt5gt7esn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lACJBDW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwaatwlr93rnt5gt7esn.png" alt="Methods have their own auth header assignment" width="864" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Speaking on the request process, I particularly struggled with OAuth 1.0, holy moly 😭. At first, the idea of having this crazy looking value that required the existence of a bunch of keys and secrets seemed daunting. I was later able to come to terms with the fact that the only real work being done is just generating the OAuth signature. &lt;a href="https://developer.twitter.com/en/docs/authentication/oauth-1-0a/authorizing-a-request"&gt;This page&lt;/a&gt; in twitter and &lt;a href="https://oauth1.wp-api.org/docs/basics/Signing.html"&gt;this blog&lt;/a&gt; helped me figure out the requirements needed to generate the signature for the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  The structure of the whole app
&lt;/h3&gt;

&lt;p&gt;I quite enjoyed separating the process from the library of code containing the logic. What I mean by that is the console app that is essentially running this process doesn’t actually have any other physical files inside it that help it run the twitter stream or retweet etc. That lives in a different project whose output type is a library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_FEWQTMu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1l30w2rcs98xyduzzfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_FEWQTMu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1l30w2rcs98xyduzzfb.png" alt="Simplest console app layout" width="267" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The structure of “listen and retweet” process
&lt;/h3&gt;

&lt;p&gt;This is just to give a clearer explanation to what was mentioned above about the &lt;code&gt;GetFilteredStream&lt;/code&gt; methods function as an argument argument. The client just listens to the stream, if anything pops up it invokes an action that it knows not much (if anything) about, as mentioned before. In this case, we're invoking the retweeting process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HXXv136e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyvq0jqrmnshoo8p9bjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HXXv136e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyvq0jqrmnshoo8p9bjv.png" alt="Chop and change" width="571" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean up and putting things on a background service
&lt;/h3&gt;

&lt;p&gt;To clean up, I decided to make the console app into something more suitable. I’ve introduced a class that inherits from the &lt;code&gt;BackgroundService&lt;/code&gt; class, named &lt;code&gt;TwitterStreamService&lt;/code&gt;. The &lt;code&gt;BackgroundService&lt;/code&gt; class is a &lt;em&gt;“base class for implementing a long running hosted service”&lt;/em&gt;, I couldn't have said it better myself; (&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&amp;amp;tabs=visual-studio#:~:text=BackgroundService%20is%20a%20base%20class%20for%20implementing%20a%20long%20running%20IHostedService."&gt;link here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I used to inherit from &lt;code&gt;IHostedService&lt;/code&gt; myself but I had to deal with implementing its other methods such as start and stop async. This &lt;code&gt;BackgroundService&lt;/code&gt; class does so and only lets us deal with one method, it takes care of the rest. You can see how it's set up in this (&lt;a href="https://github.com/aspnet/Hosting/blob/master/src/Microsoft.Extensions.Hosting.Abstractions/BackgroundService.cs"&gt;repo here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rx6QHpWi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lyhfh4k3qxxopc1wja15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rx6QHpWi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lyhfh4k3qxxopc1wja15.png" alt="Inheriting from BackgroundService.cs" width="880" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to start making this background service work, I would have to do a couple of things first in the &lt;code&gt;program.cs&lt;/code&gt; file; The first thing would be to create a new instance of the &lt;code&gt;HostBuilder&lt;/code&gt; (via the &lt;code&gt;Host.CreateDefaultBuilder&lt;/code&gt; method), this would help in establishing a ground for me to create this console-based service and add any dependencies needed to it. The second step is to actually register those dependencies, some of which can be seen in the constructors of some of the pictures already displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X8PkYrWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8ybhozg487tqgz6ha8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X8PkYrWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8ybhozg487tqgz6ha8s.png" alt="ConfigureServices method" width="759" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve taken a note to mention the significance in ensuring that the twitter client stays as a transient, as I wouldn't want to mix up OAuth requirements between the streaming (which wants OAuth 2.0) and the retweet post requests (which wants OAuth 1.0). The twitter stream and the commands which use these transient clients can be singletons themselves.&lt;/p&gt;

&lt;p&gt;I’ve probably made an unnecessary meal of this, but I’ve learnt quite a few things! Namely, about HTTP streaming and how certain values in the response headers can hint at the intent of the response itself. It was also fun adding background services and revisiting hosted services in console apps. The OAuth 1.0 process was probably my biggest struggle, coming to terms with something that looks fairly daunting at the start is an achievement within itself; and it provided me with new knowledge in OAuth 1.0 which is cool!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Iamabdul/DotNetTwitterBot"&gt;This link here&lt;/a&gt; is the git repo to this project, let me know how many wtf per seconds you experience 😂&lt;/p&gt;

&lt;p&gt;My next step for this will be two things, to establish some CRUD rules operations via API endpoints (using the latest .NET 6 features – which should be fun) and to also attempt hosting this in my raspberry pi (in no particular order). Can’t wait, see you there! 💨💨💨🕺&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>twitter</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
