<?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: John Enad</title>
    <description>The latest articles on DEV Community by John Enad (@jenad88).</description>
    <link>https://dev.to/jenad88</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%2F998694%2F3ec61b68-420e-4ab4-b4c7-1c744d2dee43.jpg</url>
      <title>DEV Community: John Enad</title>
      <link>https://dev.to/jenad88</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jenad88"/>
    <language>en</language>
    <item>
      <title>How to Learn FastAPI Fast</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sat, 26 Aug 2023 17:23:59 +0000</pubDate>
      <link>https://dev.to/jenad88/how-to-learn-fastapi-fast-1h6i</link>
      <guid>https://dev.to/jenad88/how-to-learn-fastapi-fast-1h6i</guid>
      <description>&lt;p&gt;FastAPI is a modern, high-performance web framework for building APIs that run on Python. It has gained a lot of popularity over the past few years. However, it does come with a little bit of learning curve. I am squarely in the middle of this FastAPI Learning Journey and this post aims to share my strategy for learning new programming technologies that have worked well for me in the past. This might help guide beginning software developers who are interested in learning FastAPI.&lt;/p&gt;

&lt;p&gt;My first strategy is to “Understand the Basics”. It’s extremely important to first understand the basics before diving into the advanced topics. My plan is to start by reading the official FastAPI documentation (&lt;a href="https://fastapi.tiangolo.com/"&gt;https://fastapi.tiangolo.com/&lt;/a&gt;). The documentation is well-structured and covers everything you need to know to get started. You can also take advantage of various online resources such as YouTube, blogs and online forums (&lt;a href="https://www.freecodecamp.org/news/search/?query=fastapi"&gt;https://www.freecodecamp.org/news/search/?query=fastapi&lt;/a&gt; and &lt;a href="https://www.tutorialspoint.com/fastapi/index.htm"&gt;https://www.tutorialspoint.com/fastapi/index.htm&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;My second strategy is to “Practice Constantly”. To learn anything fast, you need to practice constantly. Build your own projects and APIs while following tutorials. Put them on your Github. Don’t just practice writing the code but also actually do the testing and debugging of your code. This will not only help you get better at understanding FastAPI, but it also promotes your growth as a developer.&lt;/p&gt;

&lt;p&gt;“Take Advantage of FastAPI Libraries”. When I was learning ReactJS, I would use Google the list of common React/JavaScript packages and try them out. I am also doing the same thing as I learn FastAPI since it too has various libraries that can help you reduce the amount of time it takes to write API advanced functionalities. These features can be easily integrated into your project. Take advantage of libraries such as SQLAlchemy, Pydantic and many others.&lt;/p&gt;

&lt;p&gt;Finally, “Collaborate with Others”. Collaborating with others can be a great way to learn FastAPI fast. Reach out to other teams in your company that also it. Joining communities such as FastAPI Discord and Slack communities can be helpful. You can also pair program with friends or colleagues that are knowledgeable about it. In addition, if you are into it, contributing to open-source FastAPI projects can give you hands-on experience with the framework.&lt;/p&gt;

&lt;p&gt;I believe that with the right approach, anyone can learn FastAPI fast. This blog post has outlined the four tips that I use to learn FastAPI fast. Whether you’re just starting or already have some experience, it is my hope that these tips can help you achieve success faster.&lt;/p&gt;

</description>
      <category>fastapi</category>
      <category>python</category>
    </item>
    <item>
      <title>Tidbits: TailwindCSS and Next.js</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sun, 09 Jul 2023 02:49:30 +0000</pubDate>
      <link>https://dev.to/jenad88/tidbits-tailwindcss-and-nextjs-38b4</link>
      <guid>https://dev.to/jenad88/tidbits-tailwindcss-and-nextjs-38b4</guid>
      <description>&lt;p&gt;This short journal entry sums up the stuff I've been doing the past week in my spare time. I've been going through a couple of &lt;a href="https://www.udemy.com/user/sahand-ghavidel/"&gt;Dr Sahand Ghavidel&lt;/a&gt; video course entitled "Mastering Tailwind CSS 3.0 Build Two Dynamic Projects" where he shows how to use Tailwind to partially clone a couple of pages from Tesla and Instagram.&lt;/p&gt;

&lt;p&gt;I then proceeded to learn from &lt;a href="https://www.udemy.com/courses/search/?src=ukw&amp;amp;q=brad+traversy"&gt;Brad Traversy&lt;/a&gt; from his video course called "Tailwind CSS From Scratch - Learn by Building Projects" where he goes through 5 mini-projects and several projects.&lt;/p&gt;

&lt;p&gt;I then started looking into Next.js and read some of the documentation and then decided to just jump in and create a repo so that I can actually start trying it's many exciting new features. Once the repo is set up, I will apply what I've learned from Tailwind to test different layouts, pages and components.&lt;/p&gt;

&lt;p&gt;I've created a bunch of repos from this week's learnings at: &lt;a href="https://github.com/jenad88"&gt;https://github.com/jenad88&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Tidbits: Learning TailwindCSS</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sun, 02 Jul 2023 14:17:32 +0000</pubDate>
      <link>https://dev.to/jenad88/tidbits-learning-tailwindcss-e1n</link>
      <guid>https://dev.to/jenad88/tidbits-learning-tailwindcss-e1n</guid>
      <description>&lt;p&gt;Tidbits are little bits of news about things I'm working on or learning that I just wanted to chronicle.&lt;/p&gt;

&lt;p&gt;The past couple of days and this coming week, My focus has been on learning &lt;a href="https://tailwindcss.com/"&gt;TailwindCSS&lt;/a&gt;. I just recently learned about this amazing CSS framework because in the past year or so, I have been more focused on AWS and back-end work. Any UI features I had worked on used a different &lt;a href="https://reactstrap.github.io/?path=/story/home-installation--page"&gt;Reactstrap&lt;/a&gt;-based proprietary framework.&lt;/p&gt;

&lt;p&gt;The resources I've used are of course it's &lt;a href="https://tailwindcss.com/docs/installation"&gt;documentation&lt;/a&gt;, and a few courses from &lt;a href="https://www.udemy.com/user/sahand-ghavidel/"&gt;Sahand Ghavidel&lt;/a&gt;. He has a handful of project-based courses at Udemy on TailwindCSS. I will continue to learn about TailwindCSS for the next couple of weeks before starting my portfolio project. Heads down for awhile!&lt;/p&gt;

&lt;p&gt;These are 2 Github repos I have created thus far based on the Sahad's course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jenad88/tailwind-company-example"&gt;Tesla clone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jenad88/tailwind-social"&gt;Instagram clone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>My Portfolio Journal: Portfolio page up and getting organized</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sat, 01 Jul 2023 14:00:00 +0000</pubDate>
      <link>https://dev.to/jenad88/portfolio-series-portfolio-page-up-and-getting-organized-37pa</link>
      <guid>https://dev.to/jenad88/portfolio-series-portfolio-page-up-and-getting-organized-37pa</guid>
      <description>&lt;p&gt;As is usually the case when going off to start a new venture, the initial enthusiasm runs high until reality sets in. I'm still starting off so I'm in the "high" phase :D&lt;/p&gt;

&lt;p&gt;After having created and customized my Developer Portfolio Site: &lt;a href="https://www.johnenad.com/"&gt;johnenadFolio&lt;/a&gt;, I just wanted a quick way to deploy it. Good thing I found this well-written article by &lt;a href="https://medium.com/@jonathans199"&gt;Jonathan Sanchez&lt;/a&gt; on how to &lt;a href="https://medium.com/boca-code/deploy-your-react-app-to-aws-s3-bucket-and-with-ci-cd-1c9ce03023c2"&gt;"Deploy React App to AWS S3 bucket"&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Finally with my &lt;a href="https://www.johnenad.com/"&gt;Developer Portfolio&lt;/a&gt; up and running, I set out to organize myself and went ahead to create a free account on &lt;a href="https://www.notion.so/product/ai"&gt;Notion&lt;/a&gt;. For those not familiar with Notion, it is an amazing product that helps individuals, teams and enterprises get organized, take notes or develop a knowledge and track goals and tasks. It uses AI and you can take advantage of thousands of templates that will enhance the way you work. For me, it's hard to describe it because of the myriad of things that it can do that just makes work easier for its users.&lt;/p&gt;

&lt;p&gt;Once that was done, I had to decide on the portfolio project(s) I would work on and after some deliberation, I settled on making an a crude CRM application, a basic Account system and a simple Purchasing system. I hope to just implement maybe a couple of features for each one of them.&lt;/p&gt;

&lt;p&gt;Next step, would be to familiarize myself with &lt;a href="https://www.notion.so/product/ai"&gt;Notion&lt;/a&gt; so I can get more details on my plan together. I'll keep you posted! :)&lt;/p&gt;

</description>
      <category>devjournal</category>
    </item>
    <item>
      <title>Tidbits: Awesome React book</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Tue, 27 Jun 2023 01:42:02 +0000</pubDate>
      <link>https://dev.to/jenad88/tidbits-awesome-react-book-200o</link>
      <guid>https://dev.to/jenad88/tidbits-awesome-react-book-200o</guid>
      <description>&lt;p&gt;This is a short post about a book I just started reading and following along. It's called &lt;a href="https://www.packtpub.com/product/react-application-architecture-for-production"&gt;React Application Architecture for Production&lt;/a&gt; by &lt;a href="https://twitter.com/alan_alickovic"&gt;Alan Alickovic&lt;/a&gt; from &lt;a href="https://www.packtpub.com/"&gt;packtpub.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would highly recommend this book for intermediate web developers who are in the middle of building large-scale applications. It uses &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt;, &lt;a href="https://www.typescriptlang.org/docs/"&gt;TypeScript&lt;/a&gt;, MSW library for mocking endpoints and covers unit testing with Jest, integration testing with Jest and React Testing Library and Cypress for end-to-end testing.&lt;/p&gt;

&lt;p&gt;It uses GitHub Actions (which I haven't tried yet) for CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;I hope to apply some of the techniques I learn from this book to my portfolio projects which I plan to start real soon.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Working on my Portfolio Website</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sat, 24 Jun 2023 23:09:33 +0000</pubDate>
      <link>https://dev.to/jenad88/working-on-my-portfolio-website-378f</link>
      <guid>https://dev.to/jenad88/working-on-my-portfolio-website-378f</guid>
      <description>&lt;p&gt;After I had spent about an hour strategizing about blogging, I concluded that my time and energy would best be served by working on portfolio projects and writing about the various technologies and techniques applied to them as I'm developing them. This way, I end up with working projects which are something tangible and being able to actually share them instead of just writing about whatever random software-related stuff I happened to be dabbling with at the moment.&lt;/p&gt;

&lt;p&gt;With that realization, I turned my focus on finally creating my own Portfolio website that serve as the gateway to future projects  that I will working on. I figured that the fastest and best way to establish one would be by using whatever open source solution that was already available. I happened to find an amazing portfolio template that I particularly liked called &lt;a href="https://github.com/saadpasta/developerFolio"&gt;developerFolio&lt;/a&gt;. It was created by a Pakistani software developer named &lt;a href="https://github.com/saadpasta"&gt;Saad Pasta&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has saved me a lot of time because it is easy to setup, change and deploy. Although I haven't deployed it yet, I was able to commit an initial version to my github repository at: &lt;a href="https://github.com/jenad88/johnenadFolio"&gt;https://github.com/jenad88/johnenadFolio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now, my next steps would be to deploy this website to maybe an S3 bucket and then start planning for projects to work on. The following are some of the possible things I will start really soon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hotel booking&lt;/li&gt;
&lt;li&gt;Something involving Real Estate&lt;/li&gt;
&lt;li&gt;E-Commerce-related modules&lt;/li&gt;
&lt;li&gt;E-Learning application&lt;/li&gt;
&lt;li&gt;Job Board&lt;/li&gt;
&lt;li&gt;Image management application&lt;/li&gt;
&lt;li&gt;Fiverr Clone&lt;/li&gt;
&lt;li&gt;TaskRabbit clone&lt;/li&gt;
&lt;li&gt;Spotify Clone&lt;/li&gt;
&lt;li&gt;Youtube Clone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have a portfolio website and plan to create one, check out &lt;a href="https://github.com/saadpasta/developerFolio"&gt;developerFolio&lt;/a&gt; and you'll have it done in an hour or two.&lt;/p&gt;

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

&lt;p&gt;I'm going to work on deploying this soon. Shoutout and many thanks to &lt;a href="https://github.com/saadpasta"&gt;Saad&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Beginner Spring Boot Series - Part 3: @Profile and @Beans example</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sun, 18 Jun 2023 13:34:23 +0000</pubDate>
      <link>https://dev.to/jenad88/beginner-spring-boot-series-part-3-profile-and-beans-example-lc2</link>
      <guid>https://dev.to/jenad88/beginner-spring-boot-series-part-3-profile-and-beans-example-lc2</guid>
      <description>&lt;p&gt;With spring beans and profiles, Spring (Boot) gives us a very powerful feature to configure our applications. Spring has the &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt; annotation to control which beans get added to the application context. Only beans associated with the active profile are used.&lt;/p&gt;

&lt;p&gt;This post is about how I usually use &lt;a class="mentioned-user" href="https://dev.to/beans"&gt;@beans&lt;/a&gt; and &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt; annotation.&lt;/p&gt;

&lt;p&gt;You can check out the sample code at this Github repository: &lt;a href="https://github.com/jenad88/enad-spring-1"&gt;https://github.com/jenad88/enad-spring-1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a Spring Boot application is started with certain profile(s) activated, the application can react in a certain way based on the activated profile(s).&lt;/p&gt;

&lt;p&gt;The way I use profiles, is per environment. So first, I identify the different environments my application will reside. In my case: local, dev, qa, staging, prod&lt;/p&gt;

&lt;p&gt;Then for each profile, I create a application.properties file (or .yaml file if you prefer those). The convention is to append the profile name to the filename. For example: application-local.properties or application-prod.properties.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MaOXirX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3j292wc1ndkifb79xib8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MaOXirX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3j292wc1ndkifb79xib8.png" alt="Image description" width="392" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each of the profile .properties file would then be filled with the configuration that would be used for that profile/environment. In my case, for local:&lt;br&gt;
services.myservice=false&lt;br&gt;
app.message1=Hello World - LOCAL&lt;br&gt;
app.value1=THIS IS LOCAL&lt;/p&gt;

&lt;p&gt;and for prod:&lt;br&gt;
services.myservice=true&lt;br&gt;
app.message1=Hello World - PROD&lt;br&gt;
app.value1=THIS IS PROD&lt;/p&gt;

&lt;p&gt;I do the same for the rest of the other .properties files...&lt;/p&gt;

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

&lt;p&gt;I then create a Spring Bean which uses those configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyBeanImpl implements MyBean {

    private String message1;
    private String value1;

    public MyBeanImpl(@Value("${app.message1}") String message1, @Value("${app.value1}") String value1) {
        this.message1 = message1;
        this.value1 = value1;
    }

    public String getMessage1() {
        return message1;
    }

    public String getValue1() {
        return value1;
    }

    @Override
    public String doSomething() {
        String result = getClass() + ".doSomething() - " + this.getMessage1() + "=" + this.getValue1();
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when Spring Boot starts it will automatically grab the right configuration file based on the profile that is active. Then it loads the configuration properties into the spring beans from that file.&lt;/p&gt;

&lt;p&gt;I then create a couple of services called NonProdServiceImpl and ProdServiceImpl which both implement the MyService interface.&lt;br&gt;
In the constructor, it receives the MyBean spring bean. Each of the services is also marked with the &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt; annotation. The ProdServiceImpl has &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt;("prod"). That directs Spring Boot to use this if the active profile is prod. The NonProdServiceImpl has &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt;("!prod"). This tells Spring Boot that if the active profile is not prod, then use this service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.johnenad.enadspring1.service;

import com.johnenad.enadspring1.config.MyBean;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Profile("!prod")
@Service
public class NonProdMyServiceImpl implements MyService {

    private MyBean myBean;

    public NonProdMyServiceImpl(MyBean myBean) {
        this.myBean = myBean;
    }

    @Override
    public String doSomething() {
        String result = String.format("NonProdMyServiceImpl: %s=%s", myBean.getMessage1(), myBean.getValue1());
        // do non-production-specific stuff here
        System.out.println(result);
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the prod version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.johnenad.enadspring1.service;

import com.johnenad.enadspring1.config.MyBean;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Profile("prod")
@Service
public class ProdMyServiceImpl implements MyService {

    private MyBean myBean;

    public ProdMyServiceImpl(MyBean myBean) {
        this.myBean = myBean;
    }

    @Override
    public String doSomething() {
        String result = String.format("ProdMyServiceImpl: %s=%s", myBean.getMessage1(), myBean.getValue1());
        // do production-specific stuff here
        System.out.println(result);
        return result;
    }
}

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

&lt;/div&gt;



&lt;p&gt;A MyServiceController controller is then created that has a MyService injected (@Autowired) in its constructor. The service that is injected depends on which profile is active.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.johnenad.enadspring1.controller.v1;

import com.johnenad.enadspring1.dto.MyServiceResponse;
import com.johnenad.enadspring1.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static com.johnenad.enadspring1.util.DemoUtil.PATH_V1;

@RestController
@RequestMapping(PATH_V1 + "/myservice")
public class MyServiceController implements MyServiceApi {

    private final MyService myService;

    @Autowired
    public MyServiceController(MyService myService) {
        this.myService = myService;
    }

    @Override
    public ResponseEntity&amp;lt;MyServiceResponse&amp;gt; doSomething() {
        try {
            String result = myService.doSomething();

            if (result == null || result.isEmpty()) {
                return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NO_CONTENT);
            }
            return new ResponseEntity&amp;lt;&amp;gt;(MyServiceResponse.builder().data(result).build(), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;How do we tell Spring Boot which profile is the active profile? Just make sure that when you launch your application, we use the -D parameter with the active profile.&lt;/p&gt;

&lt;p&gt;Example: -Dspring.profiles.active=prod&lt;/p&gt;

&lt;p&gt;When running locally, using IntelliJ IDEA, here is how my configuration looks: (Note the Active profiles field)&lt;/p&gt;

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

&lt;p&gt;If you have a jar file:&lt;br&gt;
java -jar -Dspring.profiles.active=prod enad-spring-1-0.0.1-SNAPSHOT.jar&lt;/p&gt;

&lt;p&gt;You can check out the sample code at this Github repository: &lt;a href="https://github.com/jenad88/enad-spring-1"&gt;https://github.com/jenad88/enad-spring-1&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Beginner Spring Boot Series - Part 2</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Mon, 12 Jun 2023 18:00:13 +0000</pubDate>
      <link>https://dev.to/jenad88/beginner-spring-boot-series-part-2-2h7n</link>
      <guid>https://dev.to/jenad88/beginner-spring-boot-series-part-2-2h7n</guid>
      <description>&lt;p&gt;Resuming our Spring Boot Beginner Series, I am continuing with the Simple Person CRUD example. I figured that it's better to use a newer version of Spring Boot version to 3.1.0. This decision caused has caused changes that would impact the JPA/Hibernate configurations and the OpenAPI setup. There are some nuances there which I'll point out later on. It is important to note that this is just a demo project in fact it employs some bad practices like hard-coded usernames and passwords. This should never be allowed in a real application.&lt;/p&gt;

&lt;p&gt;As per my promise in the last post, I've uploaded the updated code to my GitHub repository, accessible here: &lt;a href="https://github.com/jenad88/enad-spring-1"&gt;https://github.com/jenad88/enad-spring-1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project follows a structure that has been organized into several distinct packages: controller, service, repository, model, and DTO, along with a few others.&lt;/p&gt;

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

&lt;p&gt;The role of the controller code is to serve as the visible interface for users and other APIs. This segment of the code handles incoming requests, performs validations where necessary, and hands it over to the service code for the execution of business processing. Once it retrieves the results from the invoked service, the controller leverages the DTO code to shape the returned response.&lt;/p&gt;

&lt;p&gt;Our project's service code forms the backbone of our business logic and processing. It has an understanding of the DTO and model structures. This takes inputs from the controller (along with the configuration/environment) and uses them to execute specific tasks, and upon completion, relays the results back to the controller. Whenever required, it "talks" with databases or other services.&lt;/p&gt;

&lt;p&gt;The repository code serves as the project's connection with the database. It is in-charge of data storage and retrieval and is thus integrated with the model structures which I'll explain next.&lt;/p&gt;

&lt;p&gt;The model package houses code that mirrors the data in the database tables. For instance, in our simple project, we have a 'Person' class that aligns with the 'Person' table in MySQL. The fields within the 'Person' class map directly to the respective columns in the 'Person' table.&lt;/p&gt;

&lt;p&gt;The DTO package hosts the data structures used when invoking controller API methods and when returning data from the API.&lt;/p&gt;

&lt;p&gt;A core principle used in our project is the idea of 'Separation of Concerns'. This often used (and over-mentioned) concept concerns code organization. In simple terms, it means that your code should be grouped together based on its functionality. The controller focuses on controlling request flow, the service is dedicated to executing business logic, and the repository looks after data storage and retrieval.&lt;/p&gt;

&lt;p&gt;Why is it important? For one, it clarifies the roles and responsibilities of each code grouping and thus helps make the code easier to understand. More importantly, this significantly makes it easier to create and execute unit tests (a potential future topic).&lt;/p&gt;

&lt;p&gt;The PersonController class is used to handle HTTP requests related to 'Person' entities. Because it implements the PersonApi interface, it provides the concrete implementation of the methods defined in the PersonApi interface. The PersonController has a dependency on PersonService which is used to perform business process operations related to 'Person' entities.&lt;/p&gt;

&lt;p&gt;Below are the methods of the PersonController:&lt;/p&gt;

&lt;p&gt;getAll(): Handles HTTP GET requests to fetch all 'Person' entities.&lt;/p&gt;

&lt;p&gt;getPersonById(long id): Handles HTTP GET requests for a specific 'Person' entity, identified by its unique 'id'.&lt;/p&gt;

&lt;p&gt;createPerson(PersonDTO personDTO): Handles HTTP POST requests to create a new 'Person' entity.&lt;/p&gt;

&lt;p&gt;updatePerson(long id, PersonDTO personDTO): Handles HTTP PUT requests to update an existing 'Person' entity. It uses the provided 'id' to identify the 'Person' entity to be updated.&lt;/p&gt;

&lt;p&gt;deletePerson(long id): Handles HTTP DELETE requests to remove an existing 'Person' entity.&lt;/p&gt;

&lt;p&gt;findByActive(): Handles HTTP GET requests to fetch 'Person' entities marked as 'active'.&lt;/p&gt;

&lt;p&gt;Each method returns an instance of ResponseEntity, a class that represents the entire HTTP response, including headers, body, and status. It is used to fully configure the HTTP response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping(PATH_V1 + "/persons")
public class PersonController implements PersonApi {

    private final PersonService personService;

    @Autowired
    public PersonController(PersonService personService) {
        this.personService = personService;
    }

    public ResponseEntity&amp;lt;PersonResponse&amp;gt; getAll() {
        try {

            List&amp;lt;PersonDTO&amp;gt; persons = new ArrayList&amp;lt;&amp;gt;(personService.fetchAll());

            if (persons.isEmpty()) {
                return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NO_CONTENT);
            }

            return new ResponseEntity&amp;lt;&amp;gt;(PersonResponse.builder().data(persons).build(), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity&amp;lt;&amp;gt;(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    public ResponseEntity&amp;lt;PersonResponse&amp;gt; getPersonById(long id) {
        Optional&amp;lt;PersonDTO&amp;gt; personOpt = personService.getById(id);

        return personOpt.map(personDTO -&amp;gt; new ResponseEntity&amp;lt;&amp;gt;(PersonResponse.builder().data(personDTO).build(), HttpStatus.OK))
                .orElseGet(() -&amp;gt; new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NOT_FOUND));
    }

    public ResponseEntity&amp;lt;PersonResponse&amp;gt; createPerson(PersonDTO personDTO) {
        try {
            personDTO.setActive(true);
            PersonDTO newPerson = personService.save(personDTO);
            return new ResponseEntity&amp;lt;&amp;gt;(PersonResponse.builder().data(newPerson).build(), HttpStatus.CREATED);
        } catch (Exception e) {
            return new ResponseEntity&amp;lt;&amp;gt;(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    public ResponseEntity&amp;lt;PersonResponse&amp;gt; updatePerson(long id, PersonDTO personDTO) {
        personDTO.setId(id);
        PersonDTO updatedPersonDTO = personService.update(personDTO);
        if (updatedPersonDTO == null) {
            return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NOT_FOUND);
        }
        PersonResponse personResponse = PersonResponse.builder().data(updatedPersonDTO).build();

        return new ResponseEntity&amp;lt;&amp;gt;(personResponse, HttpStatus.OK);
    }

    public ResponseEntity&amp;lt;HttpStatus&amp;gt; deletePerson(long id) {
        try {
            personService.delete(id);
            return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NO_CONTENT);
        } catch (Exception e) {
            return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    public ResponseEntity&amp;lt;PersonResponse&amp;gt; findByActive() {
        try {
            List&amp;lt;PersonDTO&amp;gt; persons = personService.fetchByActive(true);

            if (persons.isEmpty()) {
                return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.NO_CONTENT);
            }
            return new ResponseEntity&amp;lt;&amp;gt;(PersonResponse.builder().data(persons).build(), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity&amp;lt;&amp;gt;(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

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

&lt;/div&gt;



&lt;p&gt;The PersonServiceImpl class which lives in the service package is responsible for business logic and can call methods in repository classes. Because it implements the PersonService interface, it provides all the concrete implementation of the methods defined in that interface.&lt;/p&gt;

&lt;p&gt;It has a PersonRepository instance which is used to interact with the MySQL database used in the application.&lt;/p&gt;

&lt;p&gt;Below are the methods of the PersonServiceImpl&lt;/p&gt;

&lt;p&gt;fetchAll(): This method retrieves all 'Person' entities from the repository, converts them to DTOs (Data Transfer Objects), and returns them as a list.&lt;/p&gt;

&lt;p&gt;fetchByActive(boolean active): This method retrieves all 'Person' entities with a specific active status from the repository, converts them to DTOs, and returns them as a list.&lt;/p&gt;

&lt;p&gt;getById(long id): This method retrieves a 'Person' entity with a specific 'id'. If such an entity exists, it converts it to a DTO and wraps it in an Optional. If no such entity exists, it returns Optional.empty().&lt;/p&gt;

&lt;p&gt;update(PersonDTO personDTO): This method updates an existing 'Person' entity. It retrieves the 'Person' entity from the repository, updates its fields, saves the updated entity back to the repository, and returns the updated entity as a DTO. If no such entity exists, it returns null.&lt;/p&gt;

&lt;p&gt;add(String firstName, String lastName, boolean active): This method creates a new 'Person' entity, saves it to the repository, and returns the saved entity as a DTO.&lt;/p&gt;

&lt;p&gt;delete(long id): This method deletes a 'Person' entity with a specific 'id'. If no such entity exists, it does nothing.&lt;/p&gt;

&lt;p&gt;save(PersonDTO personDTO): This method creates a new 'Person' entity from a DTO, saves it to the repository, and returns the saved entity as a DTO.&lt;/p&gt;

&lt;p&gt;The class uses PersonDTO.convert() to convert between 'Person' entities and DTOs. This is an example of separation of concerns: the service layer handles the business logic, while the DTOs are used for transferring data between different application layers (in this case, between the service layer and a web layer).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class PersonServiceImpl implements PersonService {

    final private PersonRepository personRepository;

    @Autowired
    public PersonServiceImpl(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @Override
    public List&amp;lt;PersonDTO&amp;gt; fetchAll() {
        List&amp;lt;Person&amp;gt; persons = personRepository.findAll();
        return PersonDTO.convert(persons);
    }

    @Override
    public List&amp;lt;PersonDTO&amp;gt; fetchByActive(boolean active) {
        List&amp;lt;Person&amp;gt; persons = personRepository.findByActive(active);
        return PersonDTO.convert(persons);
    }

    @Override
    public Optional&amp;lt;PersonDTO&amp;gt; getById(long id) {
        Optional&amp;lt;Person&amp;gt; personOpt = personRepository.findById(id);
        return personOpt.map(PersonDTO::convert);
    }

    @Override
    public PersonDTO update(PersonDTO personDTO) {
        Optional&amp;lt;Person&amp;gt; p = personRepository.findById(personDTO.getId());
        if (p.isEmpty()) {
            return null;
        }

        Person person = p.get();
        person.setFirstName(personDTO.getFirstName());
        person.setLastName(personDTO.getLastName());
        person.setActive(personDTO.isActive());

        Person updatedPerson = personRepository.save(person);
        return PersonDTO.convert(updatedPerson);
    }

    @Override
    public PersonDTO add(String firstName, String lastName, boolean active) {
        Person person = personRepository.save(new Person(firstName, lastName, active));
        return PersonDTO.convert(person);
    }

    @Override
    public void delete(long id) {
        Optional&amp;lt;Person&amp;gt; person = personRepository.findById(id);
        person.ifPresent(personRepository::delete);
    }

    @Override
    public PersonDTO save(PersonDTO personDTO) {
        Person person = new Person();
        person.setFirstName(personDTO.getFirstName());
        person.setLastName(personDTO.getLastName());
        person.setActive(personDTO.isActive());

        Person savedPerson = personRepository.save(person);
        return PersonDTO.convert(savedPerson);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This post is getting a bit on the long side so will stop here. In the next post, I will continue improving this application.&lt;/p&gt;

&lt;p&gt;The GitHub repository can be found here: &lt;a href="https://github.com/jenad88/enad-spring-1"&gt;https://github.com/jenad88/enad-spring-1&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Day 46-47: Beginner FastAPI Series - Part 3</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Thu, 08 Jun 2023 11:01:00 +0000</pubDate>
      <link>https://dev.to/jenad88/day-46-47-beginner-fastapi-series-part-3-4i14</link>
      <guid>https://dev.to/jenad88/day-46-47-beginner-fastapi-series-part-3-4i14</guid>
      <description>&lt;p&gt;In this post, we'll go into a little more detail with FastAPI which I've heard is great for building APIs in Python. We'll develop a simple and straightforward API, using a 'Person' as our model with three attributes: first_name, last_name, and active. The aim is to understand and apply the techniques and concepts that I've been reading about in the last couple of days.&lt;/p&gt;

&lt;p&gt;In part 2 we showed how routes work. This time we're actually going to work with a Person model and create functionality to persist and retrieve data from a database. For this exercise, I've chosen SQLite because its lightweight and because of it's disk-based properties. SqlLite is supposedly the most used database engine in the world because it is embedded in a lot of mobile phones and used in a lot of daily applications as well.&lt;/p&gt;

&lt;p&gt;On a side note, I might have some future posts involving PostgreSQL and even MySQL because, why not? It sounds like a exercise. But anyway check out SQLite [here] &lt;a href="https://www.sqlitetutorial.net/"&gt;https://www.sqlitetutorial.net/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Our tool we're going to be using for interfacing with the SQLite database is &lt;a href="https://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt;, a SQL toolkit that provides a unified API for various relational databases. If you installed FastAPI with &lt;code&gt;pip install "fastapi[all]"&lt;/code&gt;, &lt;a href="https://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt; is already part of your setup. but if you opted for FastAPI alone, you would need to install SQLAlchemy separately with &lt;code&gt;pip install sqlalchemy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will just point out the significant points of the code. The complete code will be in a Github repository located here: &lt;a href="https://github.com/jenad88/enad-project-1"&gt;https://github.com/jenad88/enad-project-1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a db.py file that contains code that uses SQLAlchemy which is a SQL toolkit and Object-Relational Mapping (ORM) system for Python and sets up a connection with a SQLite database, then defines how sessions are created &lt;br&gt;
and finally, it sets up a Base class for defining the database tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# Create a sqlite engine instance
engine = create_engine("sqlite:///enad-core.db")

# Create SessionLocal class from sessionmaker factory
SessionLocal = sessionmaker(bind=engine, expire_on_commit=False)

# Create a DeclarativeMeta instance
Base = declarative_base()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;create_engine&lt;/code&gt; is used to set up the connection to the database, and Column, Integer, String, and Boolean are classes used to define the database table structures.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;declarative_base&lt;/code&gt; is a base class used by all the models while sessionmaker is a factory that creates new Session objects.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;create_engine&lt;/code&gt; function initializes a new engine instance for the SQLite database which stores data in a file named enad-core.db. All connections used by SQLAlchemy comes from this engine.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SessionLocal&lt;/code&gt; is created from the &lt;code&gt;sessionmaker&lt;/code&gt; factory function. I generates new Session objects when called. These objects are then used as a "handle" to the database, allowing database queries.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;declarative_base&lt;/code&gt; function is called to create a new &lt;code&gt;Base&lt;/code&gt; class. This &lt;code&gt;Base&lt;/code&gt; class serves as the base class for all SQLAlchemy models as we will show later.&lt;/p&gt;

&lt;p&gt;The start of the application is in the /backend/app folder in a file called main.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from fastapi import FastAPI
from backend.app.routers import person_routers_v1
from backend.app.db import Base, engine

def create_app():
    app = FastAPI()

    app.include_router(person_routers_v1.router, prefix="/api")

    return app

# Create the database
Base.metadata.create_all(engine)

app = create_app()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The previous code creates a FastAPI application with a set of routes and sets up the SQLite database using SQLAlchemy. &lt;/p&gt;

&lt;p&gt;Apart from fastapi being imported, the person_routers_v1 module which contain 'person' routers is also imported. Base and engine are SQLAlchemy classes used for interacting with the database.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;create_app&lt;/code&gt; is a function that defines and returns a FastAPI application instance. It includes the routes from the person_routers_v1 router and has a prefix of "/api". This means that all routes defined in person_routers_v1 will have "/api" added before their route. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Base.metadata.create_all(engine)&lt;/code&gt; line creates all the tables in the database from classes that inherit from Base. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;app = create_app()&lt;/code&gt; creates an instance of the FastAPI application by calling the &lt;code&gt;create_app&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The remaining code has then been organized into three folders: models, routers and schemas&lt;/p&gt;

&lt;p&gt;In the routers folder we have the person_routers_v1.py file. It contains the CRUD implementation (Create, Retrieve, Update, Delete) API for a 'Person' model using the FastAPI framework and uses SQLAlchemy for database communication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from fastapi import APIRouter, Depends, HTTPException, status
from backend.app.db import SessionLocal
from sqlalchemy.orm import Session

import backend.app.models.person_models_v1 as person_models_v1
import backend.app.schemas.person_schemas_v1 as person_schemas_v1

def get_session():
    session = SessionLocal()
    try:
        yield session
    finally:
        session.close()


router = APIRouter(
    prefix="/v1/persons",
    tags=["persons"],
    responses={404: {"description": "Not found"}},
)

@router.get("", response_model=person_schemas_v1.PersonListResponse, status_code=status.HTTP_200_OK)
def get_persons(session: Session = Depends(get_session)):

    # get all persons
    persons_list = session.query(person_models_v1.Person).all()

    return {"data": persons_list}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The rest can be found in the repository: &lt;a href="https://github.com/jenad88/enad-project-1"&gt;https://github.com/jenad88/enad-project-1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;get_session&lt;/code&gt; function establishes a connection with the database using SQLAlchemy's &lt;code&gt;SessionLocal&lt;/code&gt; and then yields the session for the transaction. After the transaction, the session is closed.&lt;/p&gt;

&lt;p&gt;An APIRouter router is initialized with a URL prefix and some metadata for documentation and error handling.&lt;/p&gt;

&lt;p&gt;The router decorator is used to associate HTTP request methods (GET, POST, PUT, DELETE) with their respective functions. These functions are responsible for handling CRUD operations on the 'Person' model.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;get_persons&lt;/code&gt; function retrieves all Person entries from the database and returns them.&lt;/p&gt;

&lt;p&gt;it's getting a bit long so will end here for now.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Beginner Spring Boot Series - Part 1</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Wed, 07 Jun 2023 01:44:44 +0000</pubDate>
      <link>https://dev.to/jenad88/beginner-spring-boot-series-part-1-4c7b</link>
      <guid>https://dev.to/jenad88/beginner-spring-boot-series-part-1-4c7b</guid>
      <description>&lt;p&gt;Just as I was wrapping up my second FastAPI course, a thought occurred to me: How would this code look if it were written in Java/Spring Boot? Despite the differences between these two platforms, there are some similarities. So I went ahead and created a Spring Boot equivalent of my "&lt;a href="https://dev.to/jenad88/day-45-beginner-fastapi-series-part-2-p99"&gt;Day 45: Beginner FastAPI Series - Part 2&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;Before getting started, Here's the desired route definitions I referred to in the FastAPI Series:&lt;/p&gt;

&lt;p&gt;GET /api/persons: Retrieves all persons&lt;br&gt;
GET /api/persons/{id}: Fetches a specific person's details&lt;br&gt;
POST /api/persons/{id}: Creates a new person record&lt;br&gt;
PUT /api/persons/{id}: Updates an existing person's details&lt;br&gt;
DELETE /api/persons/{id}: Removes a single person record&lt;/p&gt;

&lt;p&gt;I use IntelliJ IDEA as my Java IDE, (My favorite Java IDE!) and to kick things off, I created a new project, and named it "enad-spring-1". &lt;/p&gt;

&lt;p&gt;I managed to capture a couple of screenshots of my configuration selections. I also decided to just use Spring 2.7.12 and Java 17&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wq9HyE88--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6uxloxzlhtgyz2sqtgqz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wq9HyE88--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6uxloxzlhtgyz2sqtgqz.png" alt="Image description" width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Very much like what I mentioned in my initial post on FastAPI, what I'm presenting here is a preliminary setup. It's not a finished product, but a starting point designed to speed up our project's momentum. It's like a bunch of placeholder methods that currently return basic strings. However, in subsequent posts, we'll refactor them into full-fledged functions that interacts with the 'Person' entity.&lt;/p&gt;

&lt;p&gt;So switching gears, here's the code in the 'PersonController' class within the controller package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.johnenad.enadspring1.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/persons")
public class PersonController {

    @GetMapping("")
    public String getPersons() {
        return "read persons list";
    }

    @PostMapping("")
    public String createPerson() {
        return "create person item";
    }

    @GetMapping("/{id}")
    public String getPerson(@PathVariable("id") int id) {
        return String.format("read persons item id: %s", id);
    }

    @PutMapping("/{id}")
    public String updatePerson(@PathVariable("id") int id) {
        return String.format("update persons item id: %s", id);
    }

    @DeleteMapping("/{id}")
    public String deletePerson(@PathVariable("id") int id) {
        return String.format("delete persons item id: %s", id);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit: I've incorporated the 'open-api' dependency in the project's 'pom.xml' file to facilitate OpenAPI integration with Spring Boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springdoc&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springdoc-openapi-ui&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.7.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spring Initializer generates this boilerplate code for our application as the starting point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
public class EnadSpring1Application {
    public static void main(String[] args) {
        SpringApplication.run(EnadSpring1Application.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Launching the application is simple. Just open the file mentioned above, select Run - Run 'EnadSpring1Application', or use the keyboard shortcut, Shift-F10.&lt;/p&gt;

&lt;p&gt;Once the application is up and running, fire up your browser and navigate to &lt;a href="http://localhost:8080/api/persons"&gt;http://localhost:8080/api/persons&lt;/a&gt;. Voila! The application will respond with the text "read persons list". It's important to note that Spring Boot designates port 8080 as the default localhost port.&lt;/p&gt;

&lt;p&gt;Test out the dynamic routes by visiting &lt;a href="http://localhost:8080/api/persons/1"&gt;http://localhost:8080/api/persons/1&lt;/a&gt;. The terminal digit '1' in the URL is interpreted as the person's ID. Spring Boot's intuitive routing feature aligns the URL with the pre-established route, replacing {id} with '1'.&lt;/p&gt;

&lt;p&gt;Now, let's revisit the 'Edit' segment I mentioned earlier. The 'springdoc-openapi-ui' dependency was added to furnish the application with interactive OpenAPI documentation.&lt;/p&gt;

&lt;p&gt;To see this feature firsthand, enter: &lt;a href="http://localhost:8080/swagger-ui.html"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The interactive documentation allows you to test all the routes in your application. For instance, expand 'GET /api/persons', select the 'Try it out' option followed by the 'Execute' button to invoke the getPersons method, just as you would via your browser.&lt;/p&gt;

&lt;p&gt;This marks the beginning of my Spring Boot series and it will be somewhat parallel at times with the FastAPI Python series. It's going to be exciting because we will be able to see both slowly evolve over time.&lt;/p&gt;

&lt;p&gt;The next installment of this new Spring Boot series will go deeper into developing our 'Person' entity and making our methods work with it.&lt;/p&gt;

&lt;p&gt;Note: In the next post, I will put the code in a public repo at Github&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Day 45: Beginner FastAPI Series - Part 2</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Tue, 06 Jun 2023 04:00:00 +0000</pubDate>
      <link>https://dev.to/jenad88/day-45-beginner-fastapi-series-part-2-p99</link>
      <guid>https://dev.to/jenad88/day-45-beginner-fastapi-series-part-2-p99</guid>
      <description>&lt;p&gt;It's time to add the routes I listed in Part 1 to our FastAPI application and associating them with functions. This is just the initial setup to keep this project moving forward and this is far from the final product. At this time, all these methods will simply return a string of text, but they will eventually be modified to perform specific actions on the 'Person' entity.&lt;/p&gt;

&lt;p&gt;These routes should be appended to the main.py file in the app folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.get("/api/persons")
def get_persons():
    return "read persons list"

@app.post("/api/persons")
def create_person():
    return "create person item"

@app.get("/api/persons/{id}")
def get_person(id: int):
    return f"read persons item id: {id}"

@app.put("/api/persons/{id}")
def update_person(id: int):
    return f"update persons item id: {id}"

@app.delete("/api/persons/{id}")
def delete_person(id: int):
    return f"delete persons item id: {id}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just in case the application isn't running here is how to run it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uvicorn app.main:app --host localhost --port 8000 --reload&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With these routes implemented, you can turn your browser to &lt;code&gt;http://localhost:8000/api/persons&lt;/code&gt;. The application will then respond with the text "read persons list".&lt;/p&gt;

&lt;p&gt;The dynamic routes will also work. Try visiting &lt;code&gt;http://localhost:8000/api/persons/1&lt;/code&gt;. The number '1' at the end of the URL will be recognized as the person's ID. FastAPI's routing feature will match the URL with the specified route and will replace &lt;code&gt;{id}&lt;/code&gt; with '1'.&lt;/p&gt;

&lt;p&gt;One of the really cool features of FastAPI is its built-in support for OpenAPI and JSON Schema. What this means is that it will automatically generate API documentation. We don't need to manually create an API documentation! &lt;/p&gt;

&lt;p&gt;To see this firsthand, just type &lt;code&gt;http://localhost:8000/docs&lt;/code&gt; into your browser's address bar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xMNnfBmj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lxnyijf1mihzac8bsbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xMNnfBmj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lxnyijf1mihzac8bsbe.png" alt="Image description" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The interactive documentation that is displayed can be used to test all the routes in your application. Just expand 'GET /api/persons' and click the 'Try it out' button. Then, click the blue 'Execute' button to call the &lt;code&gt;get_persons&lt;/code&gt; method, just like you would from the browser.&lt;/p&gt;

&lt;p&gt;I know I'm moving a little bit slower that I wanted but I also need to pace myself as there are other things I'm simultaneously studying at the moment (hint: 2 things and they both start with 'T').&lt;/p&gt;

&lt;p&gt;Nevertheless, we have only scratched the surface but have already seen sparks of FastAPI's brilliance. I really like what I'm seeing and think FastAPI is coherent and well-structured.&lt;/p&gt;

&lt;p&gt;The next installment of this series will go deeper into developing our 'Person' entity and making our methods work with it.&lt;/p&gt;

&lt;p&gt;Note: In the next post, I will put the code in a public repo at Github&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Day 43-44: Beginner FastAPI Series - Part 1</title>
      <dc:creator>John Enad</dc:creator>
      <pubDate>Sun, 04 Jun 2023 13:21:29 +0000</pubDate>
      <link>https://dev.to/jenad88/day-43-44-beginner-fastapi-series-part-1-8oc</link>
      <guid>https://dev.to/jenad88/day-43-44-beginner-fastapi-series-part-1-8oc</guid>
      <description>&lt;p&gt;I've recently come across an amazing web framework for building APIs with Python, and I'm excited to learn it. To document this, I'm starting a new series that chronicles my adventures (and misadventures!) as I slowly get familiar with it.&lt;/p&gt;

&lt;p&gt;FastAPI bills itself as a modern, high-performance web framework for building APIs. It compares its speed to NodeJS and Go, and touts itself as one of the fastest Python frameworks around. I poked around its documentation and looked up a examples, and liked what I saw So without a second thought, I decided to dive right in!&lt;/p&gt;

&lt;p&gt;I took a quick pause to think about what I was going to build and I aimed for simplicity so I settled on developing a basic CRUD (Create, Read, Update, Delete) project for a Person with just four fields: id, first_name, last_name, and active.&lt;/p&gt;

&lt;p&gt;To those who might want to follow along, here are the prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.11 installed.&lt;/li&gt;
&lt;li&gt;VSCode installed with a basic understanding of setting up a venv environment.&lt;/li&gt;
&lt;li&gt;A fundamental grasp of Python. Some familiarity with FastAPI would be advantageous.&lt;/li&gt;
&lt;li&gt;Basic understanding of HTTP and REST.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, I mapped out the routes for the API and here's what I came up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP METHOD  ROUTE
GET          /api/persons  (Retrieves all persons)
GET          /api/persons/:person_id  (Retrieves a single person)
POST         /api/persons/:person_id  (Creates a new person)
PUT          /api/persons/:person_id  (Updates an existing person)
DELETE       /api/persons/:person_id  (Deletes a single person)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then created a new folder titled 'enad-project-1' to house the project. Launching VSCode, I initiated Git in a VSCode terminal with the command: 'git init'.&lt;/p&gt;

&lt;p&gt;In the root folder, I set up a '.gitignore' file to prevent unnecessary files from being saved in our Git repository. It excludes the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.DS_Store
.idea/
__pycache__/
venv/
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set up the Python Virtual Environment (venv), I used VS Code's Command Palette to run 'Python: Create Environment', selecting 'venv'. Upon opening a new terminal, I noticed that the command-line prompt now begins with '(.venv)', signifying the active virtual environment.&lt;/p&gt;

&lt;p&gt;Now it's FastAPI time!&lt;/p&gt;

&lt;p&gt;Installing FastAPI was quick and easy with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install "fastapi[all]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I created a folder named 'app' and inside, I generated an empty file named '&lt;code&gt;__init__.py&lt;/code&gt;' which (as you may or may not know) indicates that 'app' is a Python package.&lt;/p&gt;

&lt;p&gt;After that, I created 'main.py', which had the following code to create a FastAPI application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from fastapi import FastAPI
app = FastAPI()

@app.get("/api/hello")
def root():
    return {"message": "Hello World"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I ran the application using the command:&lt;br&gt;
&lt;code&gt;uvicorn app.main:app --host localhost --port 8000 --reload'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, by navigating to &lt;a href="http://localhost:8000/api/hello"&gt;http://localhost:8000/api/hello&lt;/a&gt; in a web browser, I was greeted with the ubiquitous "Hello World"!&lt;/p&gt;

&lt;p&gt;And off we go to the races! It's the start and I'm going to continue to build on this while learning about FastAPI and Python.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
    </item>
  </channel>
</rss>
