From 46eadd7783d204f820874e0eca43c4cb1ee7bfff Mon Sep 17 00:00:00 2001 From: djmil Date: Thu, 20 Jul 2023 12:47:32 +0200 Subject: [PATCH] Update Home --- Home.md | 284 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 142 insertions(+), 142 deletions(-) diff --git a/Home.md b/Home.md index de3f4f5..e9ef6b8 100644 --- a/Home.md +++ b/Home.md @@ -1,142 +1,142 @@ -This repo is my first attempt to learn `SpringBoot` following [this](https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/introduction) tutorial. The setup is Visual Code IDE alongside with [SpringBoot](https://code.visualstudio.com/docs/java/java-spring-boot) plugin. - -# Spring Initializr - -In VsCode press `cmd+shif+p` and type `Spring Initilizr`. Choose: -- Gradle Project -- _SpringBoot version:_ latest (3.1.1) -- _project language:_ Java -- _group id:_ djmil -- _artifact id (aka project name):_ cashcard -- _packaging type:_ jar -- _java version:_ 17 -- _dependencies:_ - - SpringWeb - -Essentially, this will generate a default minimalistic jet functional SpringBoot project. Entry point, aka `main()` can be found in [src/main/java/djmil/cashcard/CashcardApplication.java](http://192.168.8.55:3000/HQLAx/FamilyCashCard/src/branch/main/src/main/java/djmil/cashcard/CashcardApplication.java). To run the application - press `ctrl+F5` or Play button in the top right corner of an editor. - -# TDD - -Software development teams love to move fast. So how do you go fast forever? By continuously improving and simplifying your code – this is called **refactoring**. Refactoring is the act of altering the implementation of a software system without altering its inputs, outputs, or behavior. One of the only ways you can safely refactor is when you have a trustworthy test suite. Which brings us to the **TDD Cycle**: - -1. **Red:** Write a failing test for the desired functionality. -2. **Green:** Implement the simplest thing that can work to make the test pass. -3. **Refactor:** Look for opportunities to simplify, reduce duplication, or otherwise improve the code without changing any behavior - to _refactor._ -4. Repeat! - -Different tests can be written at different levels of the system. At each level, there is a balance between the speed of execution, the “cost” to maintain the test, and the confidence it brings to system correctness. This hierarchy is often represented as a “testing pyramid”. - -![Testing pyramid](https://blog.missiondata.com/wp-content/uploads/MD_TestingPyramid2x-1560x1045.png "Testing pyramid") - -## Unit Tests - -[[UnitTests]] exercises a small “unit” of the system that is isolated from the rest of the system. They should be simple and speedy. You want a high ratio of Unit Tests in your testing pyramid as they’re key to designing highly cohesive, loosely coupled software. - -## Integration Tests - -[[IntegrationTests]] exercise a subset of the system and may exercise groups of units in one test. They are more complicated to write and maintain, and run slower than unit tests. - -## End-to-End Tests - -An End-to-End Test exercises the system using the same interface that a user would, such as a web browser. While extremely thorough, End-to-End Tests can be very slow and fragile because they use simulated user interactions in potentially complicated UIs. Implement the smallest number of these tests. - -# RESTful API - -In a RESTful system, data objects are called Resource Representations. The purpose of a RESTful API is to manage the state of these Resources. The chart below shows details about RESTful CRUD operations of an application. - -|Operation|API Endpoint|HTTP Method|Response Status| -|---|---|---|---| -|**C**reate|`/cashcards`|`POST`|201 (CREATED)| -|**R**ead|`/cashcards/{id}`|`GET`|200 (OK)| -|**U**pdate|`/cashcards/{id}`|`PUT`|204 (NO DATA)| -|**D**elete|`/cashcards/{id}`|`DELETE`|204 (NO DATA)| - -Another common concept associated with REST is the Hypertext Transfer Protocol. In **HTTP**, a caller sends a Request to a URI. A web server receives the request, and routes it to a request handler. The handler creates a Response, which is then sent back to the caller. - -## REST in Spring Boot - -One of the main things Spring does is to configure and instantiate objects. These objects are called *Spring Beans*, and are usually created by Spring (as opposed to using the Java `new` keyword). You can direct Spring to create Beans in several ways. - -> We will annotate a class with a `@RestController` Spring Annotation, which directs Spring to create an instance of the class during Spring’s *Component Scan* phase. This happens at application startup. The Bean is stored in Spring’s `IoC Container`. From here, the bean can be injected into any code that requests it. - -![[Pasted image 20230719102322.png]] - -## @RestController - -In Spring Web, Requests are handled by Controllers. We are going to use the more specific `RestController` annotation. The actual class shall be placed in `src/main/java/djmil/cashcard/CashCardController.java` - -```java -@RestController -public class CashCardController { -} -``` - -That’s all it takes to tell Spring: “create a REST Controller”. The Controller gets injected into Spring Web, which routes API requests (handled by the Controller) with help of [[GET#@GetMapping]] annotation to the correct method. - -## Get -**** -In [[GET]] requests, the body is empty. So, the request to read the Cash Card with an id of 123 would be: - -``` -Request: - Method: GET - URL: http://cashcard.example.com/cashcards/123 - Body: (empty) -``` - -The response to a successful Read request has a body containing the JSON representation of the Resource which was requested, with a Response Status Code of 200 (OK). So the response to the above Read request would look like this: - -``` -Response: - Status Code: 200 - Body: - { - "id": 123, - "amount": 25.00 - } -``` - -# Database - -The [**Separation of Concerns**](https://en.wikipedia.org/wiki/Separation_of_concerns) principle states that well-designed software should be modular, with each module having distinct and separate concerns from any other module. - -Up until now, our codebase only returns a hard-coded response from the Controller. This setup violates the Separation of Concerns principle by mixing the concerns of a Controller, which is an abstraction of a web interface, with the concerns of reading and writing data to a data store, such as a database. In order to solve this, we’ll use a common software architecture pattern to enforce data management separation via the **[Repository](https://www.baeldung.com/java-dao-vs-repository)** pattern. - -A common architectural framework that divides these layers, typically by function or value, such as business, data, and presentation layers, is called **Layered Architecture**. Here we can think of our Repository and Controller as two layers in a Layered Architecture. The Controller is in a layer near the Client (as it receives and responds to web requests) while the Repository is in a layer near the data store (as it reads from and writes to the data store). There may be intermediate layers as well, as dictated by business needs. - -![[Pasted image 20230719152007.png]] - -The Repository is the interface between the application and the database, and provides a **common abstraction** for any database, making it easier to switch to a different database when needed. - -[Spring Data](https://spring.io/projects/spring-data) works with Spring Boot to make database integration simple. - -## Choosing a Database - -For our database selection, we’ll use an **embedded, in-memory** database. “Embedded” simply means that it’s a Java library, so it can be added to the project just like any other dependency. “In-memory” means that it stores data in memory only, as opposed to persisting data permanent, durable storage. - -The specific in-memory database we’ll use is [H2](https://www.h2database.com/html/main.html). Fortunately, H2 is highly compatible with other relational databases, so dev-prod parity *(application might behave differently when running the in-memory database than when running in production)* won’t be a big issue. We’ll use H2 for **convenience for local development**, but want to recognize the tradeoffs. - -## Auto Configuration - -Simply by adding [[Database#Spring Data and a database dependencies]] we are getting full database functionality. This wonderfully showcases one of the most powerful features of Spring Boot: **Auto Configuration**. Without Spring Boot, we’d have to configure Spring Data to speak to H2. However, because we’ve included the Spring Data dependency (and a specific data provider, H2), Spring Boot will automatically configure your application to communicate with H2. - -## Spring Data’s CrudRepository - -For our Repository selection, we’ll use a specific type of Repository: Spring Data’s `CrudRepository`. At first glance, it’s slightly magical, but let’s unpack that magic. - -The following is a complete implementation of all CRUD operations by extending `CrudRepository`: - -```java -public interface CashCardRepository extends CrudRepository { -} -``` - -With just the above code, a caller can call any number of predefined `CrudRepository` methods, such as `findById`: - -```java -cashCard = cashCardRepository.findById(99); -``` - -You might immediately wonder: where is the implementation of the `CashCardRepository.findById()` method? `CrudRepository` and everything it inherits from is an Interface with no actual code! Well, based on the specific Spring Data framework used, which for us will be Spring Data JDBC, Spring Data takes care of this implementation for us during the IoC container startup time. The Spring runtime will then expose the repository as yet another bean that you can reference wherever needed in your application. - -As we’ve learned, there are typically trade-offs. For example the `CrudRepository` generates SQL statements to read and write your data, which is useful for many cases, but sometimes you need to write your own custom SQL statements for specific use cases. But for now, we’re happy to take advantage of its convenient, out-of-the-box methods, \ No newline at end of file +This repo is my first attempt to learn `SpringBoot` following [this](https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/introduction) tutorial. The setup is Visual Code IDE alongside with [SpringBoot](https://code.visualstudio.com/docs/java/java-spring-boot) plugin. It is also advised to read this wiki via [Obsidian](https://obsidian.md/) + +# Spring Initializr + +In VsCode press `cmd+shif+p` and type `Spring Initilizr`. Choose: +- Gradle Project +- _SpringBoot version:_ latest (3.1.1) +- _project language:_ Java +- _group id:_ djmil +- _artifact id (aka project name):_ cashcard +- _packaging type:_ jar +- _java version:_ 17 +- _dependencies:_ + - SpringWeb + +Essentially, this will generate a default minimalistic jet functional SpringBoot project. Entry point, aka `main()` can be found in [src/main/java/djmil/cashcard/CashcardApplication.java](http://192.168.8.55:3000/HQLAx/FamilyCashCard/src/branch/main/src/main/java/djmil/cashcard/CashcardApplication.java). To run the application - press `ctrl+F5` or Play button in the top right corner of an editor. + +# TDD + +Software development teams love to move fast. So how do you go fast forever? By continuously improving and simplifying your code – this is called **refactoring**. Refactoring is the act of altering the implementation of a software system without altering its inputs, outputs, or behavior. One of the only ways you can safely refactor is when you have a trustworthy test suite. Which brings us to the **TDD Cycle**: + +1. **Red:** Write a failing test for the desired functionality. +2. **Green:** Implement the simplest thing that can work to make the test pass. +3. **Refactor:** Look for opportunities to simplify, reduce duplication, or otherwise improve the code without changing any behavior - to _refactor._ +4. Repeat! + +Different tests can be written at different levels of the system. At each level, there is a balance between the speed of execution, the “cost” to maintain the test, and the confidence it brings to system correctness. This hierarchy is often represented as a “testing pyramid”. + +![Testing pyramid](https://blog.missiondata.com/wp-content/uploads/MD_TestingPyramid2x-1560x1045.png "Testing pyramid") + +## Unit Tests + +[[UnitTests]] exercises a small “unit” of the system that is isolated from the rest of the system. They should be simple and speedy. You want a high ratio of Unit Tests in your testing pyramid as they’re key to designing highly cohesive, loosely coupled software. + +## Integration Tests + +[[IntegrationTests]] exercise a subset of the system and may exercise groups of units in one test. They are more complicated to write and maintain, and run slower than unit tests. + +## End-to-End Tests + +An End-to-End Test exercises the system using the same interface that a user would, such as a web browser. While extremely thorough, End-to-End Tests can be very slow and fragile because they use simulated user interactions in potentially complicated UIs. Implement the smallest number of these tests. + +# RESTful API + +In a RESTful system, data objects are called Resource Representations. The purpose of a RESTful API is to manage the state of these Resources. The chart below shows details about RESTful CRUD operations of an application. + +|Operation|API Endpoint|HTTP Method|Response Status| +|---|---|---|---| +|**C**reate|`/cashcards`|`POST`|201 (CREATED)| +|**R**ead|`/cashcards/{id}`|`GET`|200 (OK)| +|**U**pdate|`/cashcards/{id}`|`PUT`|204 (NO DATA)| +|**D**elete|`/cashcards/{id}`|`DELETE`|204 (NO DATA)| + +Another common concept associated with REST is the Hypertext Transfer Protocol. In **HTTP**, a caller sends a Request to a URI. A web server receives the request, and routes it to a request handler. The handler creates a Response, which is then sent back to the caller. + +## REST in Spring Boot + +One of the main things Spring does is to configure and instantiate objects. These objects are called *Spring Beans*, and are usually created by Spring (as opposed to using the Java `new` keyword). You can direct Spring to create Beans in several ways. + +> We will annotate a class with a `@RestController` Spring Annotation, which directs Spring to create an instance of the class during Spring’s *Component Scan* phase. This happens at application startup. The Bean is stored in Spring’s `IoC Container`. From here, the bean can be injected into any code that requests it. + +![[Pasted image 20230719102322.png]] + +## @RestController + +In Spring Web, Requests are handled by Controllers. We are going to use the more specific `RestController` annotation. The actual class shall be placed in `src/main/java/djmil/cashcard/CashCardController.java` + +```java +@RestController +public class CashCardController { +} +``` + +That’s all it takes to tell Spring: “create a REST Controller”. The Controller gets injected into Spring Web, which routes API requests (handled by the Controller) with help of [[GET#@GetMapping]] annotation to the correct method. + +## Get + +In [[GET]] requests, the body is empty. So, the request to read the Cash Card with an id of 123 would be: + +``` +Request: + Method: GET + URL: http://cashcard.example.com/cashcards/123 + Body: (empty) +``` + +The response to a successful Read request has a body containing the JSON representation of the Resource which was requested, with a Response Status Code of 200 (OK). So the response to the above Read request would look like this: + +``` +Response: + Status Code: 200 + Body: + { + "id": 123, + "amount": 25.00 + } +``` + +# Database + +The [**Separation of Concerns**](https://en.wikipedia.org/wiki/Separation_of_concerns) principle states that well-designed software should be modular, with each module having distinct and separate concerns from any other module. + +Up until now, our codebase only returns a hard-coded response from the Controller. This setup violates the Separation of Concerns principle by mixing the concerns of a Controller, which is an abstraction of a web interface, with the concerns of reading and writing data to a data store, such as a database. In order to solve this, we’ll use a common software architecture pattern to enforce data management separation via the **[Repository](https://www.baeldung.com/java-dao-vs-repository)** pattern. + +A common architectural framework that divides these layers, typically by function or value, such as business, data, and presentation layers, is called **Layered Architecture**. Here we can think of our Repository and Controller as two layers in a Layered Architecture. The Controller is in a layer near the Client (as it receives and responds to web requests) while the Repository is in a layer near the data store (as it reads from and writes to the data store). There may be intermediate layers as well, as dictated by business needs. + +![[Pasted image 20230719152007.png]] + +The Repository is the interface between the application and the database, and provides a **common abstraction** for any database, making it easier to switch to a different database when needed. + +[Spring Data](https://spring.io/projects/spring-data) works with Spring Boot to make database integration simple. + +## Choosing a Database + +For our database selection, we’ll use an **embedded, in-memory** database. “Embedded” simply means that it’s a Java library, so it can be added to the project just like any other dependency. “In-memory” means that it stores data in memory only, as opposed to persisting data permanent, durable storage. + +The specific in-memory database we’ll use is [H2](https://www.h2database.com/html/main.html). Fortunately, H2 is highly compatible with other relational databases, so dev-prod parity *(application might behave differently when running the in-memory database than when running in production)* won’t be a big issue. We’ll use H2 for **convenience for local development**, but want to recognize the tradeoffs. + +## Auto Configuration + +Simply by adding [[Database#Spring Data and a database dependencies]] we are getting full database functionality. This wonderfully showcases one of the most powerful features of Spring Boot: **Auto Configuration**. Without Spring Boot, we’d have to configure Spring Data to speak to H2. However, because we’ve included the Spring Data dependency (and a specific data provider, H2), Spring Boot will automatically configure your application to communicate with H2. + +## Spring Data’s CrudRepository + +For our Repository selection, we’ll use a specific type of Repository: Spring Data’s `CrudRepository`. At first glance, it’s slightly magical, but let’s unpack that magic. + +The following is a complete implementation of all CRUD operations by extending `CrudRepository`: + +```java +public interface CashCardRepository extends CrudRepository { +} +``` + +With just the above code, a caller can call any number of predefined `CrudRepository` methods, such as `findById`: + +```java +cashCard = cashCardRepository.findById(99); +``` + +You might immediately wonder: where is the implementation of the `CashCardRepository.findById()` method? `CrudRepository` and everything it inherits from is an Interface with no actual code! Well, based on the specific Spring Data framework used, which for us will be Spring Data JDBC, Spring Data takes care of this implementation for us during the IoC container startup time. The Spring runtime will then expose the repository as yet another bean that you can reference wherever needed in your application. + +As we’ve learned, there are typically trade-offs. For example the `CrudRepository` generates SQL statements to read and write your data, which is useful for many cases, but sometimes you need to write your own custom SQL statements for specific use cases. But for now, we’re happy to take advantage of its convenient, out-of-the-box methods. \ No newline at end of file