{"id":30100195,"url":"https://github.com/rohitpshelar/quarkus_tutorials","last_synced_at":"2026-04-20T13:07:26.369Z","repository":{"id":306319953,"uuid":"1025761184","full_name":"rohitpshelar/quarkus_tutorials","owner":"rohitpshelar","description":"learn quarkus","archived":false,"fork":false,"pushed_at":"2025-08-05T13:24:10.000Z","size":51,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-05T15:21:16.837Z","etag":null,"topics":["circuit-breaker","cors","cross-origin-resource-sharing","fallback","fault-tolerance","hibernate-orm","intellij","java21","microprofile","quarkus","swagger-ui"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rohitpshelar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-24T18:55:50.000Z","updated_at":"2025-08-05T13:24:14.000Z","dependencies_parsed_at":"2025-07-25T01:33:39.546Z","dependency_job_id":"8e2ba6f3-e5d2-452f-a2fa-972eef34417a","html_url":"https://github.com/rohitpshelar/quarkus_tutorials","commit_stats":null,"previous_names":["rohitpshelar/quarkus_tutorials"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rohitpshelar/quarkus_tutorials","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohitpshelar%2Fquarkus_tutorials","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohitpshelar%2Fquarkus_tutorials/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohitpshelar%2Fquarkus_tutorials/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohitpshelar%2Fquarkus_tutorials/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rohitpshelar","download_url":"https://codeload.github.com/rohitpshelar/quarkus_tutorials/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohitpshelar%2Fquarkus_tutorials/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32048474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circuit-breaker","cors","cross-origin-resource-sharing","fallback","fault-tolerance","hibernate-orm","intellij","java21","microprofile","quarkus","swagger-ui"],"created_at":"2025-08-09T16:01:35.865Z","updated_at":"2026-04-20T13:07:26.354Z","avatar_url":"https://github.com/rohitpshelar.png","language":"Java","readme":"# quarkus_tutorials 🎥\nhttps://youtube.com/playlist?list=PLzdlNxYnNoaf5bb-Pwb7MbWHGlRf28pVO\u0026si=fUuG6enQWCokfN4t\n\n## Spring Boot vs Quarkus Annotations Comparison 📊\n\n| Annotation Type       | Spring Boot            | Quarkus               |\n|-----------------------|------------------------|-----------------------|\n| **Main Class**        | @SpringBootApplication | @QuarkusMain          |\n| **Dependency Inj.**   | @Autowired             | @Inject               |\n| **Components**        | @Repository            | @ApplicationScoped    |\n|                       | @Service               | @ApplicationScoped    |\n|                       | @Component             | @ApplicationScoped    |\n| **Data Access**       | CrudRepository         | PanacheRepository     |\n|                       | @Entity                | @Entity               |\n|                       | @Transactional         | @Transactional        |\n| **Web**               | @RestController        | @Path                 |\n|                       | @GetMapping            | @GET                  |\n|                       | @PostMapping           | @POST                 |\n| **Testing**           | @SpringBootTest        | @QuarkusTest          |\n|                       | @MockBean              | @InjectMock           |\n| **Configuration**     | @Value                 | @ConfigProperty       |\n| **Caching**           | @EnableCaching         | @CacheResult          |\n| **Scheduling**        | @Scheduled             | @Scheduled            |\n| **Async**             | @Async                 | @Blocking/@NonBlocking|\n\n\n\n1. Support both\n\n```\nImperative -\u003e if ABC data fetched, it will search entire DB and bring record\nReactive -\u003e If ABC is fetched, it will return data 1 by 1 as it gets.\n```\n\n2. Open source\n3.  Set JAVA_HOME\n4.  Download Maven https://maven.apache.org/download.cgi \u003e Binary zip archive \u003e  keep in C:\\Program Files (x86) \u003e  set path (C:\\Program Files (x86)\\apache-maven-3.9.11\\bin) in \"PATH\" \n5.  Goto https://code.quarkus.io/ \n6. Dependency Selected \n   1. RESTEasy Classic \n   2. RESTEasy Classic Jackson\n7. Add project to intellij\n8. Add plugin in Intellij as \u003e Quarkus Tools\n9. run Project with command ```mvn quarkus:dev``` OR  ```./mvnw quarkus:dev``` (Ref : [Quarkus_README.md](Quarkus_README.md) )\n10. In 4th Lecture \n11. To check Quarkus supported Extension/Dependencies -\u003e ```mvn quarkus:list-extensions``` OR ```./mvnw quarkus:list-extensions```\n12. To Add  \u003e ```./mvnw quarkus:add-extension -Dextensions=\"_____\"``` OR ```mvn quarkus:add-extension -Dextensions=\"Mutiny\"```\n13. In 6th Part - All 4 API added [MobileResource.java](src/main/java/com/learn/resource/MobileResource.java) and their Postman collection [quarkus-tutorial-mvn.postman_collection.json](quarkus-tutorial-mvn.postman_collection.json)\n14. In 7th Part - All 4 API updated with modal and 5th API ByNumber ([Mobile.java](src/main/java/com/learn/resource/Mobile.java)) and new resource [MobileResourcePart7.java](src/main/java/com/learn/resource/MobileResourcePart7.java) and their Postman collection [quarkus-tutorial-mvn.postman_collection.json](quarkus-tutorial-mvn.postman_collection.json)\n15. In 8th Part -\n    1. Add swagger ```mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-openapi\"```\n    2. Goto http://localhost:8080/q/swagger-ui/\n    3. To Change default swagger path (http://localhost:8080/q/swagger-ui/) to custom (http://localhost:8080/swag/)\n       ```properties\n          quarkus.swagger-ui.path=/swag\n       ```\n    4. To disable swagger UI Path\n       ```properties\n          quarkus.swagger-ui.always-include=false\n       ```\n16. In 9th Part -  Bring data from other Micro service\n    1. Add following extension/dependency :\n       1. \"REST Client\" to call remote API ```mvn quarkus:add-extension -Dextensions=\"quarkus-rest-client\"```\n       2. \"REST Client jackson\" to call remote API ```mvn quarkus:add-extension -Dextensions=\"quarkus-rest-client-jackson\"```\n       3. \"quarkus-rest-jackson\" to call remote API ```mvn quarkus:add-extension -Dextensions=\"quarkus-rest-jackson\"```\n       4. Remove quarkus-resteasy and quarkus-resteasy-jackson due to conflict regards ( Caused by: jakarta.enterprise.inject.spi.DeploymentException: Mixing Quarkus REST and RESTEasy Classic server parts is not supported )\n    2. Use DUMMY client as https://www.tvmaze.com/api\n       1. Search TV show by Id - https://api.tvmaze.com/shows/169 \n       2. Create Modal class for above response\n17. In Part-10 : cors ( Cross Origin Resource Sharing ) - allow external service to access our service ( Open  this from Browser : [Part-10.html](Part-10.html) )\n    ```properties\n    quarkus.http.cors=true\n    quarkus.http.cors.origins=*\n    ```\n    1. Allow only specific method \n    ```properties\n    quarkus.http.cors.methodshs=GET, POST\n    ```\n18. In Part-11, 12 : Microprofile Fault Tolerance\n    1. Add following extension/dependency :\n       1. \"Fault Tolerance\" to call default method if remote API offline ```mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-fault-tolerance\"```\n      \n    2. Create Fallback Method \n    ```java\n    @Fallback(fallbackMethod = \"getTvSeriesByIdFallback\")\n    ```\n    3. Retry ```@Retry(maxRetries = 2)```\n    4. Timeout ```@Timeout(1000)```\n    5. Circuit Breaker\n    ```java\n    @CircuitBreaker(\n        requestVolumeThreshold=2,\n        failureRatio=0.5,\n        delay = 10, delayUnit = ChronoUnit.SECONDS\n    )\n    ```\n    6. Git Bash Script to hit URL in loop\n    ```shell\n        while true; do sleep 1; curl http://localhost:8080/tvseries/260; echo -e '\\n'; done\n    ```\n    13. Part-13, 14 : Hibernate-ORM PanacheEntity with H2DB\n        1. \"H2DB\" - ```./mvnw quarkus:add-extension -Dextensions=\"io.quarkus:quarkus-jdbc-h2\"```\n        2. \"Hibernate ORM\" - ```./mvnw quarkus:add-extension -Dextensions=\"io.quarkus:quarkus-hibernate-orm-panache\"```\n        3. Two Types\n           1. Extend Entity Class with PanacheEntity\n           2. Implement with PanacheRepository\n        4. Mapping\n           1. One to One\n              - Add ```@OneToOne``` to secondary class\n\n                \u003ctable\u003e\n                   \u003ctr\u003e\n                      \u003ctd\u003e\n                         \u003ctable\u003e\n                            \u003ctr\u003e\n                               \u003cth colspan=\"2\"\u003eTable 1\u003c/th\u003e\n                            \u003c/tr\u003e\n                            \u003ctr\u003e\n                               \u003ctd\u003eT1_ID\u003c/td\u003e\n                               \u003ctd\u003eT1_Name\u003c/td\u003e\n                            \u003c/tr\u003e\n                         \u003c/table\u003e\n                      \u003c/td\u003e\n                      \u003ctd\u003e\n                         \u003ctable\u003e\n                            \u003ctr\u003e\n                               \u003cth colspan=\"3\"\u003eTable 2\u003c/th\u003e\n                            \u003c/tr\u003e\n                            \u003ctr\u003e\n                               \u003ctd\u003eT2_ID\u003c/td\u003e\n                               \u003ctd\u003eT2S_Name\u003c/td\u003e\n                               \u003ctd\u003eT1_ID\u003c/td\u003e\n                            \u003c/tr\u003e\n                         \u003c/table\u003e\n                      \u003c/td\u003e\n                   \u003c/tr\u003e\n                \u003c/table\u003e\n    \n               - But here we can only find Table 1 from Table 2, So\n               - We will add ```@OneToOne``` to Primary class\n\n                \u003ctable\u003e\n                   \u003ctr\u003e\n                      \u003ctd\u003e\n                         \u003ctable\u003e\n                            \u003ctr\u003e\n                               \u003cth colspan=\"3\"\u003eTable 1\u003c/th\u003e\n                            \u003c/tr\u003e\n                            \u003ctr\u003e\n                               \u003ctd\u003eT1_ID\u003c/td\u003e\n                               \u003ctd\u003eT1_Name\u003c/td\u003e\n                               \u003ctd\u003eT2_ID\u003c/td\u003e\n                            \u003c/tr\u003e\n                         \u003c/table\u003e\n                      \u003c/td\u003e\n                      \u003ctd\u003e\n                         \u003ctable\u003e\n                            \u003ctr\u003e\n                               \u003cth colspan=\"3\"\u003eTable 2\u003c/th\u003e\n                            \u003c/tr\u003e\n                            \u003ctr\u003e\n                               \u003ctd\u003eT2_ID\u003c/td\u003e\n                               \u003ctd\u003eT2S_Name\u003c/td\u003e\n                               \u003ctd\u003eT1_ID\u003c/td\u003e\n                            \u003c/tr\u003e\n                         \u003c/table\u003e\n                      \u003c/td\u003e\n                   \u003c/tr\u003e\n                \u003c/table\u003e\n               - But now we have two column on both table\n               - So to remove extra column from Primary class use in Primary class :  ```@OneToOne(mappedBy = \"\u003c*Primary class*\u003e\")```\n               - To fetch both at once use Primary class : **fetch = FetchType.EAGER** : ```@OneToOne(mappedBy = \"\u003c*Primary class*\u003e\", fetch = FetchType.EAGER)```\n               - To fix ```Infinite recursion``` - which is due to both class has ```@OneToOne``` annotation\n                 1. Add @JsonManagedReference in Primary class\n                 2. Add @JsonBackReference in secondary class\n               - To save both at Once use in Primary class  : **cascade = CascadeType.ALL** : ```@OneToOne(mappedBy = \"laptop\", fetch = FetchType.EAGER, cascade = CascadeType.ALL)```\n19. Part 29 : Logging\n    1. Info - Method info\n    2. Debug - Data Info\n    3. warning\n    4. Error\n20. Part- 30 : Exception -TODO\n21. Part - 32 : MicroProfile Health\n    1. Add ``` mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-health\"```\n    2. Two Type\n       1. Liveness [LivenessHealthCheck.java](src/main/java/com/learn/resource/part30_MicroProfile_health/LivenessHealthCheck.java) - To check Proxy/Client Connections\n       2. Readiness [ReadinessHealthCheck.java](src/main/java/com/learn/resource/part30_MicroProfile_health/ReadinessHealthCheck.java) - To check DB connection\n    3. Test URLs\n       1. http://localhost:8080/q/health-ui/\n       2. http://localhost:8080/q/health\n       3. http://localhost:8080/q/health/live\n       4. http://localhost:8080/q/health/ready\n       5. http://localhost:8080/q/health/started\n       6. http://localhost:8080/q/health/well\n22. Part-33 How to use MicroProfile Metrics \n    1. Add ```mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-metrics\"```\n    2. Types [Number.java](src/main/java/com/learn/resource/part33_microProfile_matrics/Number.java)\n       1. @Counted\n       ```json\n       {\n          \"com.learn.resource.part33_microProfile_matrics.Number.Count_checkIfPrimeNumber\": 3\n       }\n       ```\n   \n       2. @Timed\n       ```json   \n       {\n          \"com.learn.resource.part33_microProfile_matrics.Number.Time_checkIfPrimeNumber\": {\n          \"p99\": 319201.0,\n          \"min\": 15200.0,\n          \"max\": 319201.0,\n          \"mean\": 156003.43605748552,\n          \"p50\": 15600.0,\n          \"p999\": 319201.0,\n          \"stddev\": 142029.00004744556,\n          \"p95\": 319201.0,\n          \"p98\": 319201.0,\n          \"p75\": 280601.0,\n          \"fiveMinRate\": 0.2032510706679223,\n          \"fifteenMinRate\": 0.2011018917421949,\n          \"meanRate\": 0.23204665475695216,\n          \"count\": 4,\n          \"oneMinRate\": 0.21471253794774184,\n          \"elapsedTime\": 630602.0\n          }\n       }\n       ```\n       3. @Metered\n       ```json5\n       {\n          \"com.learn.resource.part33_microProfile_matrics.Number.Metered_checkIfPrimeNumber\": {\n          \"fiveMinRate\": 0.38704854970388447,\n          \"fifteenMinRate\": 0.39559850366986254,\n          \"meanRate\": 0.1737586528638574,\n          \"count\": 4,\n          \"oneMinRate\": 0.34222396825043916\n          }\n       }\n       ```\n       4. @Gauge(unit = MetricUnits.MILLISECONDS) - For Custom \n       ```json\n       {\n          \"com.learn.resource.part33_microProfile_matrics.Number.getHighestInputPrimeNumber\": 2\n       }\n       ```\n           \n    3. 🧪 Test URLs - http://localhost:8080/q/metrics/application\n\n24. Part-34 🔐 Authentication and Authorization using JWT Token and Roles-Based Access Control\n    1. Create two Module\n       1. App (Course) - All APIs - [course](course)\n          1. Run \n                ```shell\n                    cd .\\course\n                    mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-jwt\" \n                ```\n          2. Add in [application.properties](course/src/main/resources/application.properties)\n             ```properties\n             mp.jwt.verify.issuer=jwt-token\n             mp.jwt.verify.publickey.location=../jwt/publicKey.pem\n             ```\n          3. On Method Add ```@RolesAllowed({\"teacher\",\"admin\"})```\n       2. JWT - Generate Token - [JWT](JWT)\n           1. Run\n                ```shell\n                    cd .\\JWT\n                    mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-jwt\" \n                    mvn quarkus:add-extension -Dextensions=\"quarkus-smallrye-jwt-build\" \n                ```\n           2. Add in [application.properties](jwt-token/src/main/resources/application.properties)\n              ```properties\n              smallrye.jwt.sign.key.location=../jwt/privateKey.pem\n              ```\n       3. Generate Key 🔐\n          1. Open GitBash\n          2. Run\n          ```shell\n             mkdir jwt\n\n             openssl genrsa -out jwt/rsaPrivateKey.pem 2048\n    \n             openssl rsa -pubout -in jwt/rsaPrivateKey.pem -out jwt/publicKey.pem\n    \n             openssl pkcs8 -topk8 -nocrypt -inform pem -in jwt/rsaPrivateKey.pem -outform pem -out jwt/privateKey.pem\n    \n             chmod 600 jwt/rsaPrivateKey.pem\n    \n             chmod 600 jwt/privateKey.pem\n          ```\n          3. Folder will be created as jwt ( [jwt](jwt) ), and it will contain following files\n             1. [privateKey.pem](jwt/privateKey.pem)\n             2. [publicKey.pem](jwt/publicKey.pem)\n             3. [rsaPrivateKey.pem](jwt/rsaPrivateKey.pem)\n       4. Fix `ignored POM.XML` file issue : Goto Settings \u003e Build, Execution \u003e Build Tools \u003e Maven \u003e IgnoreFiles \u003e Untick Both Module\n       5. Validate barrier key in https://www.jwt.io/\n25. Part-35 🔐 Authentication and Authorization using Keycloak Server\n    1. Goto https://www.keycloak.org/ and download \u003e extract and goto bin folder\n    2. Open bin folder in cmd, run ```kc.bat start-dev```\n    3. Create New Realm(branch) by clinking on `master` i create as `iit`\n    4. Now goto Client and create New client -  \n       1. I created clientID and name as `iit-pune`\n       2. Client Type = OpenId\n       3. Turn on Client Authentication and Authorization\n       4. ✅ Tick on Flow \u003e  Standard Flow, Direct Access Flow\n       5. Add java URL in \u003e Root, Home\n    5. Now Roles to Client \u003e  click client 'iit-pune' \u003e Roles Tab \u003e Create Role\n    6. Now Create User \u003e fill details \u003e  Role Mapping \u003e add \u003cROLE\u003e\n    7. Add Role to Java Method with ```@RolesAllowed({\"student\",\"professor\",\"admin\"})```\n    8. Run\n       ```shell\n           cd .\\part-35-Keycloa\n           mvn quarkus:add-extension -Dextensions=\"quarkus-oidc\" \n           mvn quarkus:add-extension -Dextensions=\"quarkus-keycloak-authorization\" \n       ```\n    9. Add in [application.properties](part-35-Keycloak/src/main/resources/application.properties)\n    ```properties\n    quarkus.oidc.auth-server-url=http://localhost:8080/realms/iit\n    quarkus.oidc.client-id=iit-pune\n    quarkus.oidc.credentials.secret=Ib1ua1DwqAAjLscpLmF6n66uWbWkpVIg\n    quarkus.oidc.authentication.user-info-required=true\n    ```\n26. Part-36 How to use Lombok library\n    1. ⚠️ Never use @DATA to Entity Class - it will give exception or @Oneto*** due to circular ref\n    2. ✨ @Data Contains every thing like @Getter, @Setter, @AllArgConst , @NoArgCons\n27. Part-38 How to test secured Api\n    1. Add dependency ``` mvn quarkus:add-extension -Dextensions=\"quarkus-test-security\"```\n    2. Test Class needs to be annotated with ```@QuarkusTest ``` and ```@TestMethodOrder(MethodOrderer.OrderAnnotation.class)```\n    3. Method with ```@Test```, Optional ```@Order(1)```\n    4. JWT security can be disabled by two ways: [MobileResourceTest.java](part-35-Keycloak/src/test/java/com/learn/part7/MobileResourceTest.java)\n       1. @TestSecurity(authorizationEnabled = false) \n       2. @TestSecurity(user = \"test\", roles = \"student\")\n28. Part-37 How to convert Entity(DAO) \u003e\u003e DTO(Modal)(Data Transfer Object)\n    1. ⚠️ Issue is if we modify data in DAO after fetching and method is annotated with @Transactional then modified data gets saved in DB.\n    2. Add dependency ``` MapStruct, MapStruct-Processor, lombok-mapstruct-binding``` from MVN\n29. Part-40 How to use Hibernate Validator Extension to validate Entities\n    1. Add dependency ``` mvn quarkus:add-extension -Dextensions=\"quarkus-hibernate-validator\"```\n    2. Add Annotation to Entity (TODO : Need to check for DTO) [Citizen.java](trainig/src/main/java/com/learn/resource/part37_mapstruct/part13_hibernate_ORM/Citizen.java)\n    3. Catch validation message - Ref Add Method - [CitizenResource.java](trainig/src/main/java/com/learn/resource/part37_mapstruct/part13_hibernate_ORM/CitizenResource.java)\n    4. OR Add @VValid at input Method variable.\n30. Part-41 How to debug\n    1. when ` mvn clean quarkus:dev` then default debug port is 5005\n    2. To start with Custom Port ``` mvn clean quarkus:dev -Ddebug=8121```  \n    3. In Injellij \u003e Run \u003e  Attach To Process \u003e select port\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohitpshelar%2Fquarkus_tutorials","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frohitpshelar%2Fquarkus_tutorials","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohitpshelar%2Fquarkus_tutorials/lists"}