Migrated
This commit is contained in:
39
Advanced Programming/Annotation Repository.md
Normal file
39
Advanced Programming/Annotation Repository.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
|
||||
## Lombok
|
||||
### `@AllArgsConstructor`(onConstructor_=@Annotation)
|
||||
- Creates a public constructor which takes in all args
|
||||
- `onConstructor_`: Places an annotation on the constructor
|
||||
|
||||
### `@Data`
|
||||
A shortcut for `@ToString`, `@EqualsAndHashCode`, `@Getter` on all fields, and `@Setter` on all non-final fields
|
||||
|
||||
## Spring
|
||||
|
||||
### `RestController`
|
||||
Extends Controller. Used to declare a class as a REST controller
|
||||
### `@Autowired`
|
||||
- Annotates a constructor
|
||||
- Basically, it figures out dependency injection on its own
|
||||
|
||||
### `@[Get/Post/Put/Delete]Mapping("/path/")`
|
||||
Makes an endpoint at path.
|
||||
|
||||
### `@RequestParam`
|
||||
Describe the param and type
|
||||
|
||||
```java
|
||||
@GetMapping("/api/foos")
|
||||
@ResponseBody
|
||||
public String getFoos(@RequestParam String id) {
|
||||
return "ID: " + id;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Beans
|
||||
![[Beans.canvas|Beans]]
|
||||
|
75
Advanced Programming/Intro.md
Normal file
75
Advanced Programming/Intro.md
Normal file
@ -0,0 +1,75 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
### Point: Trying to avoid technical debt
|
||||
|
||||
In software development and other information technology fields, technical debt (also known as design debt or code debt) is the implied cost of future reworking because a solution prioritizes expedience over long-term design.
|
||||
|
||||
|
||||
## Assignment explanation
|
||||
|
||||
![[assignment_app.canvas|assignment_app]]
|
||||
![[assignment_organization.canvas|assignment_organization]]
|
||||
|
||||
So essentially, each team specifies a module, then they exchange the specifications and start working. Then, each team PRs into each other's repo and we get a working thing.
|
||||
|
||||
|
||||
## Diagramming
|
||||
Diagramming *is very important* when it comes to communication. Doesn't seem like they ***need*** us to use UML, but I'm gonna learn it anyway.
|
||||
|
||||
### C4 model
|
||||
C4 stands for Context, Containers, Components, and Code.
|
||||
1. **Context Diagram:**
|
||||
- Shows the system being modeled and its interactions with external entities such as users, systems, or services.
|
||||
- Provides a high-level overview of the system's purpose and relationships with the outside world.
|
||||
2. **Container Diagram**:
|
||||
- Breaks down the system into high-level containers (e.g., web applications, databases, microservices).
|
||||
- Shows how these containers interact with each other and with external systems.
|
||||
- Defines technologies used within each container.
|
||||
3. **Component Diagram**:
|
||||
- Focuses on the components within a container and their relationships.
|
||||
- Components represent significant building blocks like classes, libraries, or microservices.
|
||||
4. **Code** (***UML***):
|
||||
- Provides a detailed view at the code level, such as classes, methods, and relationships.
|
||||
|
||||
### Key UML Diagram Types
|
||||
|
||||
1. **Structural Diagrams**: Describe the static structure of a system.
|
||||
- **Class Diagram**: Shows classes, their attributes, methods, and relationships among objects. Fundamental to object-oriented design.
|
||||
- **Object Diagram**: Represents instances of classes (objects) at a particular moment.
|
||||
- **Component Diagram**: Illustrates the organization and dependencies among software components (e.g., libraries).
|
||||
- **Deployment Diagram**: Depicts the physical deployment of artifacts on nodes like servers or devices.
|
||||
2. **Behavioral Diagrams**: Capture the dynamic behavior of a system.
|
||||
- **Use Case Diagram**: Visualizes functional requirements and interactions between users (actors) and the system.
|
||||
- **Sequence Diagram**: Shows object interactions arranged in a time sequence.
|
||||
- **Activity Diagram**: Represents workflows of stepwise activities and actions.
|
||||
- **State Machine Diagram**: Depicts states and transitions of an object throughout its lifecycle.
|
||||
3. **Interaction Diagrams**: Focus on object interactions.
|
||||
- **Communication Diagram**: Focuses on the communication between objects and the associations between them.
|
||||
- **Timing Diagram**: Represents timing constraints on object interactions.
|
||||
|
||||
#### Relationships
|
||||
- **Association**: Related but **independent**.
|
||||
- **Aggregation**: One contains the other, but the **parts can exist independently**.
|
||||
- **Composition**: Parts **cannot exist** without the whole.
|
||||
- **Dependency**: Self-explanatory
|
||||
- **Realization**: `implements`
|
||||
- **Generalization**: `extends`
|
||||
|
||||
#### Key Components of a Sequence Diagram
|
||||
|
||||
1. **Objects/Participants**: These are the entities involved in the interaction, such as classes, components, or subsystems.
|
||||
|
||||
2. **Lifelines**: A lifeline is a dashed vertical line that represents the passage of time.
|
||||
|
||||
3. **Activation Bars**: Represent duration an object is active while processing messages
|
||||
|
||||
4. **Messages**: Arrows between lifelines that show communication between objects. Messages can be of different types:
|
||||
|
||||
- **Synchronous Messages**: Represented by a solid line with a filled arrowhead, indicating a call that waits for a return.
|
||||
- **Asynchronous Messages**: Represented by a solid line with an open arrowhead, indicating a call that doesn't wait for a response.
|
||||
- **Return Messages**: Dashed arrows that show the return of control or data after a message is processed.
|
||||
|
||||
5. **Loops and conditions**: Control flow
|
||||
|
||||
![[sequence_diagram.png]]
|
189
Advanced Programming/IoC and Spring.md
Normal file
189
Advanced Programming/IoC and Spring.md
Normal file
@ -0,0 +1,189 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
|
||||
|
||||
## IoC Definition
|
||||
|
||||
Inversion of Control is a design principle in which custom code is executed by an external code. The control of parts of your code is delegated to another logical unit.
|
||||
|
||||
>Think of when you submit assignment to Themis.
|
||||
You did not write the tests in the program, but they still get executed against your program, as long as the input and output processing is correct.
|
||||
|
||||
|
||||
## Dependency Injection
|
||||
It is a technique where an object receives (or is "injected" with) other objects that it depends on, rather than creating those objects itself.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
<u>CoffeeBean.java</u>
|
||||
```java
|
||||
public class CoffeeBean {
|
||||
private String type;
|
||||
|
||||
public CoffeeBean(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<u>Water.java</u>
|
||||
```java
|
||||
public class Water {
|
||||
private int amount;
|
||||
|
||||
public Water(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<u>CoffeeMachine.java</u>
|
||||
```java
|
||||
public class CoffeeMachine {
|
||||
private CoffeeBean coffeeBean; // <--------
|
||||
private Water water; // Dependencies
|
||||
|
||||
public CoffeeMachine(CoffeeBean coffeeBean, Water water) {
|
||||
this.coffeeBean = coffeeBean;
|
||||
this.water = water;
|
||||
}
|
||||
|
||||
public void makeCoffee() {
|
||||
if (coffeeBean == null || water == null) {
|
||||
System.out.println("He-Hell nah.");
|
||||
return;
|
||||
}
|
||||
System.out.println("Making coffee with " + coffeeBean.getType() + " beans and " + water.getAmount() + "ml of water.");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
And then when we instantiate `CoffeeMachine`, we **pass instances** of `Water` and `coffeeBean`.
|
||||
|
||||
|
||||
### How Does Spring Use DI?
|
||||
|
||||
Spring manages the **creation** and **wiring** of objects for you. Here’s how it works:
|
||||
|
||||
1. **Beans**: Objects managed by Spring.
|
||||
2. **Spring Container**: Factory which creates beans. You always need the container.
|
||||
|
||||
|
||||
### `@Container` vs `@Bean` vs `@Component`
|
||||
|
||||
- A `Component` is a `Container` all of which's methods are `Beans`
|
||||
- `Bean` is a Method managed by Spring
|
||||
- `Container` is the class decorator which tells spring that we have beans inside
|
||||
|
||||
|
||||
## Spring Basics
|
||||

|
||||
|
||||
|
||||
Spring is a **framework**, hence *its* design has to be followed.
|
||||
|
||||
### Quickstart
|
||||
1. Import (mvn)
|
||||
2. Add `@SpringBootApplication`, import and `SpringApplication.run(Main.class)`
|
||||
|
||||
#### Handling a REST client
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
|
||||
// Blah blah imports blah
|
||||
|
||||
|
||||
@Controller
|
||||
public class Control {
|
||||
|
||||
@GetMapping("/api/path_to_resource/{dynamicValue}") // <- GET
|
||||
public String lmao(@PathVariable String value) {
|
||||
return "You gave me " + value;
|
||||
}
|
||||
|
||||
@PostMapping("/api/setLol") // <- POST
|
||||
public String lmao(@RequestBody String value) {
|
||||
System.out.println("Received: " + value);
|
||||
}
|
||||
|
||||
// We can also parse json n stuff
|
||||
@PostMapping("/api/yoMama")
|
||||
public ResponseEntity<String> parseJson(@RequestBody yoMama obj) {
|
||||
String response = "Received object: name = " + obj.getName() +
|
||||
", number = " + obj.getNumber() +
|
||||
", hot = " + obj.isHot();
|
||||
|
||||
System.out.println(response);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class yoMama {
|
||||
@Getter @Setter
|
||||
private String name;
|
||||
|
||||
@Getter @Setter
|
||||
private int number;
|
||||
|
||||
@Getter @Setter
|
||||
private boolean hot;
|
||||
|
||||
public yoMama() {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Beans
|
||||
> beans can only be uses by beans
|
||||
|
||||
![[Beans.canvas|Beans]]
|
||||
### Definition
|
||||
- Any class that is a dependency and/or is dependent
|
||||
### Purpose
|
||||
- Solve the problem of dependencies by traversing the project's classes and instantiating them topologically in a procedural manner
|
||||
|
||||
### Annotations
|
||||
Check out the [[Annotation Repository]].
|
||||
|
||||
## Components
|
||||
|
||||
### Entity
|
||||
- Table in a DB
|
||||
- Annotated with `@Entity`
|
||||
- Instance corresponds to a row in the DB table
|
||||
|
||||
### DTO (Data Transfer Object)
|
||||
- Java object used to transfer data b/n layers
|
||||
- Decouple internal data from data exposed to client
|
||||
- Contain only the necessary fields
|
||||
|
||||
### Repository
|
||||
- Encapsulates storage, retrieval and search from a DB
|
||||
- Usually extended from `CrudRepository` or `JpaRepository`
|
||||
- Provides CRUD (Create, Read, Update and Delete) operations and query methods for an entity
|
||||
|
||||
### Controller
|
||||
- Handles HTTP requests and returns responses
|
||||
- Maps HTTP requests to specific methods
|
||||
- Usually annotated with `@RestController` and `@RequestMapping`
|
||||
### Service
|
||||
- Class that contains logic and operations
|
||||
- Intermediary between [Controller](IoC%20and%20Spring.md#Controller) and [Repository](IoC%20and%20Spring.md#Repository)
|
||||
- Annotated with `@Service`
|
53
Advanced Programming/Testing.md
Normal file
53
Advanced Programming/Testing.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
|
||||
|
||||
## Pyramid
|
||||
![[Testing Pyramid.png]]
|
||||
|
||||
## Negative results
|
||||
- **Error**: Mistake made by a human
|
||||
- **Fault**: A manifestation of an error in software
|
||||
- **Bug and Defect** are basically the same as Fault
|
||||
- **Failure**: Inability of a system or component to perform its required function
|
||||
|
||||
|
||||
## Types of tests
|
||||
|
||||
### Functional testing
|
||||
|
||||
| Fancy Words | Simpler Explanation | Stupid Dumb Word |
|
||||
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
||||
| Unit Testing | Testing individual components or pieces of code in isolation. | Piece by piece testing |
|
||||
| Integration Testing | Testing the interaction between integrated modules or components to ensure they work together as expected. | Mix and match testing |
|
||||
| System Testing | Testing the entire system as a whole to verify it meets specified requirements. | Whole thing testing |
|
||||
| Acceptance Testing | Testing to determine whether the system meets the business needs and requirements, often performed by the end-users. | Ready or not |
|
||||
| Regression Testing | Re-running tests to ensure that new code changes haven’t broken existing functionality. | Did we break it again? |
|
||||
| Sanity Testing | A quick round of testing to check if a specific function or bug fix works as intended. | Quick check testing |
|
||||
| Smoke Testing | A basic check to ensure the software’s core functionality works and it's stable enough for more in-depth testing. | Is it on fire? |
|
||||
| Usability Testing | Testing how user-friendly and intuitive the software is for the end-user. | Easy of use testing |
|
||||
|
||||
### Non-functional testing
|
||||
|
||||
| Fancy Words | Simpler Explanation | Stupid Dumb Word |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| Performance Testing | Testing how well the software performs under different conditions. | How fast does it run? |
|
||||
| Load Testing | Testing how the software behaves under expected user load. | How much can it carry? |
|
||||
| Stress Testing | Testing the limits of the software by pushing it beyond normal operational capacity. | When will it break? |
|
||||
| Volume Testing | Testing the software with a large amount of data to see if it handles it well. | How much data can it take? |
|
||||
| Scalability Testing | Testing how well the software scales when the user load or data volume increases. | Can it grow? |
|
||||
| Recovery Testing | Testing the software's ability to recover after a failure or crash. | Can it unfuck itself? |
|
||||
| Compatibility Testing | Testing how well the software works across different environments, platforms, or devices. | Does it work with others? |
|
||||
| Security Testing | Testing how well the software protects against unauthorized access and vulnerabilities. | Can it be broken into? |
|
||||
|
||||
## Black box vs White box
|
||||
|
||||
|
||||
| Black box | White box |
|
||||
| --------------------------------- | ---------------------- |
|
||||
| Done by tester | Done by devs |
|
||||
| Internal code unknown | Knowledge is required |
|
||||
| Functional testing | Structure testing |
|
||||
| No programming skills necessary | bruh |
|
||||
| Do it break, do it work, is nice? | Do it cover all cases? |
|
BIN
Advanced Programming/assets/UML/sequence_diagram.png
Normal file
BIN
Advanced Programming/assets/UML/sequence_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
18
Advanced Programming/assets/assignment/assignment_app.canvas
Normal file
18
Advanced Programming/assets/assignment/assignment_app.canvas
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"nodes":[
|
||||
{"id":"3fc2b54b9eadc6ba","x":239,"y":-360,"width":501,"height":357,"color":"6","type":"group","label":"Server"},
|
||||
{"id":"bafe15ec55f029a6","x":-180,"y":-360,"width":602,"height":140,"color":"5","type":"group","label":"Client-side"},
|
||||
{"id":"8f80fb123ea6ce09","type":"text","text":"REST Client\n(e.g. `requests` )","x":47,"y":-320,"width":192,"height":60},
|
||||
{"id":"3cfeacd18cd26023","type":"text","text":"User","x":-140,"y":-304,"width":100,"height":29},
|
||||
{"id":"aa15bb82396562f8","type":"text","text":"Book Review API","x":414,"y":-320,"width":191,"height":60},
|
||||
{"id":"e14bb42f26a15f31","x":260,"y":-140,"width":214,"height":117,"type":"text","text":"API Service (spring)\nExpose endpoints to manage books and reviews."},
|
||||
{"id":"ac364961ecf80527","type":"text","text":"Database (MySQL)\n\nStore resources","x":509,"y":-140,"width":214,"height":117}
|
||||
],
|
||||
"edges":[
|
||||
{"id":"902c39262a6ace6a","fromNode":"3cfeacd18cd26023","fromSide":"right","toNode":"8f80fb123ea6ce09","toSide":"left"},
|
||||
{"id":"6ac86a9e5be59149","fromNode":"8f80fb123ea6ce09","fromSide":"right","toNode":"aa15bb82396562f8","toSide":"left"},
|
||||
{"id":"7913e3356f9e0f7d","fromNode":"e14bb42f26a15f31","fromSide":"top","toNode":"aa15bb82396562f8","toSide":"bottom"},
|
||||
{"id":"215231208aa4fd5a","fromNode":"ac364961ecf80527","fromSide":"top","toNode":"aa15bb82396562f8","toSide":"bottom"},
|
||||
{"id":"f2b912e7b34b6df2","fromNode":"e14bb42f26a15f31","fromSide":"right","toNode":"ac364961ecf80527","toSide":"left"}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"nodes":[
|
||||
{"id":"96f9d1aa2dfe6e72","type":"file","file":"Advanced Programming/assets/assignment/assignment_app.canvas","x":-120,"y":-340,"width":400,"height":400},
|
||||
{"id":"aaa14d4a63d50f5b","type":"text","text":"Book Management Module","x":-144,"y":222,"width":206,"height":87},
|
||||
{"id":"e8482c8d0391157a","type":"text","text":"Group 1","x":-205,"y":406,"width":123,"height":60,"color":"4"},
|
||||
{"id":"8ae0f3cd568d7382","type":"text","text":"Review Management Mode","x":200,"y":222,"width":211,"height":87},
|
||||
{"id":"43a3e65e358e014b","type":"text","text":"Group 1","x":139,"y":406,"width":123,"height":60,"color":"4"},
|
||||
{"id":"7eec19f08b2193b6","type":"text","text":"Group 2","x":349,"y":406,"width":125,"height":60,"color":"1"},
|
||||
{"id":"beea6cec3cb68314","type":"text","text":"Group 2","x":0,"y":406,"width":125,"height":60,"color":"1"}
|
||||
],
|
||||
"edges":[
|
||||
{"id":"71a504bf559dfe18","fromNode":"96f9d1aa2dfe6e72","fromSide":"bottom","toNode":"aaa14d4a63d50f5b","toSide":"top"},
|
||||
{"id":"d39fe30e3ea5696a","fromNode":"96f9d1aa2dfe6e72","fromSide":"bottom","toNode":"8ae0f3cd568d7382","toSide":"top"},
|
||||
{"id":"8edc4e274f6adbb7","fromNode":"aaa14d4a63d50f5b","fromSide":"bottom","toNode":"e8482c8d0391157a","toSide":"top","label":"Specify"},
|
||||
{"id":"c93e390557a144b8","fromNode":"aaa14d4a63d50f5b","fromSide":"bottom","toNode":"beea6cec3cb68314","toSide":"top","label":"Develop"},
|
||||
{"id":"a4dc36f27812fb63","fromNode":"8ae0f3cd568d7382","fromSide":"bottom","toNode":"43a3e65e358e014b","toSide":"top","label":"Develop"},
|
||||
{"id":"32534b3546e962c4","fromNode":"8ae0f3cd568d7382","fromSide":"bottom","toNode":"7eec19f08b2193b6","toSide":"top","label":"Specify"}
|
||||
]
|
||||
}
|
15
Advanced Programming/assets/spring/Beans.canvas
Normal file
15
Advanced Programming/assets/spring/Beans.canvas
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"nodes":[
|
||||
{"id":"e19bd648197c7e91","type":"text","text":"@Component","x":-40,"y":-200,"width":163,"height":60,"color":"1"},
|
||||
{"id":"c629af864eb7638e","type":"text","text":"@Service","x":-341,"y":-20,"width":250,"height":60,"color":"3"},
|
||||
{"id":"04cbffca8594824f","type":"text","text":"@Controller","x":-45,"y":-20,"width":173,"height":60,"color":"5"},
|
||||
{"id":"2b772d03013468ca","type":"text","text":"@Repository","x":195,"y":-20,"width":250,"height":60,"color":"6"},
|
||||
{"id":"d611968995b82f13","type":"text","text":"@RestController","x":-83,"y":140,"width":250,"height":60,"color":"5"}
|
||||
],
|
||||
"edges":[
|
||||
{"id":"dff0e847a79aaed0","fromNode":"e19bd648197c7e91","fromSide":"bottom","toNode":"c629af864eb7638e","toSide":"top"},
|
||||
{"id":"d79330e26a43a6ec","fromNode":"e19bd648197c7e91","fromSide":"bottom","toNode":"04cbffca8594824f","toSide":"top"},
|
||||
{"id":"c9e60f81cb276612","fromNode":"04cbffca8594824f","fromSide":"bottom","toNode":"d611968995b82f13","toSide":"top"},
|
||||
{"id":"435c4bfbc0474449","fromNode":"e19bd648197c7e91","fromSide":"bottom","toNode":"2b772d03013468ca","toSide":"top"}
|
||||
]
|
||||
}
|
BIN
Advanced Programming/assets/tests/Testing Pyramid.png
Normal file
BIN
Advanced Programming/assets/tests/Testing Pyramid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
162
Advanced Programming/projects/API Design Research.md
Normal file
162
Advanced Programming/projects/API Design Research.md
Normal file
@ -0,0 +1,162 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
- [Updating information](#Updating%20information)
|
||||
- [The existence of the `PATCH` request](#The%20existence%20of%20the%20%60PATCH%60%20request)
|
||||
- [Usage of `PUT`](#Usage%20of%20%60PUT%60)
|
||||
- [Complete request example](#Complete%20request%20example)
|
||||
- [Incomplete request example](#Incomplete%20request%20example)
|
||||
- [Usage of `POST`](#Usage%20of%20%60POST%60)
|
||||
- [General "style" remarks](#General%20%22style%22%20remarks)
|
||||
- [Conclusion / TL;DR](#Conclusion%20/%20TL;DR)
|
||||
|
||||
## Updating information
|
||||
Can we have optional fields in the update `PUT` and `POST` request?
|
||||
|
||||
### The existence of the `PATCH` request
|
||||
>The **`PATCH`** HTTP method applies partial modifications to a resource.
|
||||
>`PATCH` is somewhat analogous to the "update" concept found in [CRUD](https://developer.mozilla.org/en-US/docs/Glossary/CRUD) (in general, HTTP is different than [CRUD](https://developer.mozilla.org/en-US/docs/Glossary/CRUD), and the two should not be confused).[^1]
|
||||
|
||||
|
||||
Hence, this definition also answers the question as to why we **should be careful with the usage of `PATCH`** if we consider it.
|
||||
|
||||
### Usage of `PUT`
|
||||
>The PUT method requests that the state of the target resource be
|
||||
created or replaced with the state **defined by the representation**
|
||||
**enclosed in the request message payload**. [^3]
|
||||
|
||||
This implies that complete resource representation **is required** (all the fields), as Jackson(Spring) will reset the missing ones to their default values (e.g. int = 0, boolean = false, String = null, etc.)
|
||||
|
||||
|
||||
#### Complete request example
|
||||
|
||||
*Request:*
|
||||
```json
|
||||
{
|
||||
"isbn": "978-3-16-148410-0",
|
||||
"name": "Among us story",
|
||||
"author": "Yo mama",
|
||||
"genre": "Horror",
|
||||
"publisher": "Team 22",
|
||||
"publishDate": "2023-09-01",
|
||||
"pages": 320
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
*Response:*
|
||||
```json
|
||||
<<< 200 OK
|
||||
{
|
||||
"isbn": "978-3-16-148410-0",
|
||||
"name": "Among us story",
|
||||
"author": "Yo mama",
|
||||
"genre": "Horror",
|
||||
"publisher": "Team 22",
|
||||
"publishDate": "2023-09-01",
|
||||
"pages": 320
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Incomplete request example
|
||||
(this is assuming the above request happened already)
|
||||
*Request:*
|
||||
```json
|
||||
{
|
||||
"isbn": "978-3-16-148410-0",
|
||||
"name": "Among us story",
|
||||
|
||||
|
||||
"publisher": "Team 22",
|
||||
|
||||
"pages": 320
|
||||
}
|
||||
```
|
||||
|
||||
*Response*:
|
||||
```json
|
||||
|
||||
<<< 200 OK
|
||||
{
|
||||
"isbn": "978-3-16-148410-0",
|
||||
"name": "Among us story",
|
||||
"author": null,
|
||||
"genre": null,
|
||||
"publisher": "Team 22",
|
||||
"publishDate": null,
|
||||
"pages": 320
|
||||
}
|
||||
```
|
||||
### Usage of `POST`
|
||||
Contrary to `PUT`:
|
||||
>The `POST` method is **used to request that the target resource process the enclosed representation according to the resource's own specific semantics**. The meaning of a `POST` request is determined by the server and is usually dependent on the resource identified by the Request-URI.[^4]
|
||||
|
||||
Therefore we *can* send requests which contain data that are non-complete resource representations. We do have to explain this to the other team tho...
|
||||
|
||||
i.e.
|
||||
*Request:*
|
||||
```json
|
||||
{
|
||||
"isbn": "978-3-16-148410-0"
|
||||
}
|
||||
```
|
||||
|
||||
*Response:*
|
||||
``` json
|
||||
<<< 201 Created
|
||||
{
|
||||
"isbn": "978-3-16-148410-0",
|
||||
"name": null,
|
||||
"author": null,
|
||||
"genre": null,
|
||||
"publisher": null,
|
||||
"publishDate": null,
|
||||
"pages": 0
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## General "style" remarks
|
||||
(based on the API conventions + CRUD principle)
|
||||
>The base URL should be neat, elegant, and simple so that developers using your product can easily use them in their web applications. A long and difficult-to-read base URL is not just bad to look at, but can also be prone to mistakes when trying to recode it. Nouns should always be trusted.[^2]
|
||||
|
||||
Hence, using a verb in `POST /api/v1/book/create` and `PUT /api/v1/book/update` is not ideal.
|
||||
|
||||
Table[^2] of common conventions for the usage of HTTP requests:
|
||||
|
||||
|
||||
|
||||
| **Resource** | `POST` | `GET` | `PUT` | `DELETE` |
|
||||
| ------------------- | --------------------------------- | ----------------------------------- | --------------------------------------------- | -------------------------------- |
|
||||
| /customers | Create a new customer | Retrieve all customers | Bulk update of customers | Remove all customers |
|
||||
| /customers/1 | Error | Retrieve the details for customer 1 | Update the details of customer 1 if it exists | Remove customer 1 |
|
||||
| /customers/1/orders | Create a new order for customer 1 | Retrieve all orders for customer 1 | Bulk update of orders for customer 1 | Remove all orders for customer 1 |
|
||||
|
||||
Hence, in our case:
|
||||
|
||||
| **Resource** | `POST` | `GET` | `PUT` | `DELETE` |
|
||||
| ------------- | ----------------- | -------------------------------------------------------- | ------------------------------------------------ | ----------------------- |
|
||||
| /books | Create a new book | Retrieve all books (+ optional parameters for filtering) | 405 | Remove all books |
|
||||
| /books/{isbn} | 405 | Retrieve the details for book with `isbn` | Update the details of book with `isbn` if exists | Remove book with `isbn` |
|
||||
|
||||
|
||||
|
||||
## Conclusion / TL;DR
|
||||
Given the information provided above, I propose we change the current specification as follows:
|
||||
|
||||
| Method | Old URL/Description | New URL/Description | Reasoning |
|
||||
| -------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `POST` | `/api/v1/book/create` - Create book - pass JSON body (isbn is required) | `/api/v1/books` - Create a book - pass JSON body (isbn is required) | Use resource-based naming convention (`books` as a collection). HTTP POST implies creation; no need for `/create`. |
|
||||
| `PUT` | `/api/v1/book/update` - Update book - pass JSON body (isbn is required) | `/api/v1/books/{isbn}` - Update a specific book - pass JSON body | Use path parameter (`{isbn}`) to specify which book to update. HTTP PUT implies updating a specific resource. |
|
||||
| `GET` | `/api/v1/book?genre={genre}&author={author}&data="csv"` - Get book(s) by property in csv/json format | `/api/v1/books?genre={genre}&author={author}` - Get books by property. Use `Accept` header for csv/json format | Use plural `books` for collections. Use HTTP `Accept` header for content negotiation (CSV/JSON), keeping URLs clean. |
|
||||
| `DELETE` | `/api/v1/book?genre={genre}&author={author}` - Delete book(s) by property | `/api/v1/books` - Delete books - pass filter criteria in body or delete one by `/api/v1/books/{isbn}` | `DELETE` requests with body for filtering criteria, or use path param for deleting a single resource for better clarity. |
|
||||
| `POST` | `/api/v1/book/import?data="csv"` - Import books from csv/json file (isbn is required for each) | `/api/v1/books/import` - Import books from CSV/JSON file - pass file in body; use `Content-Type` header | Use resource-based naming (`books/import`). The `Content-Type` header indicates file type (CSV/JSON); keep query params clean. |
|
||||
|
||||
|
||||
|
||||
[^1]: [Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH)
|
||||
[^2]: [Swagger](https://swagger.io/resources/articles/best-practices-in-api-design/)
|
||||
[^3]: [RFC 7231 - PUT](https://datatracker.ietf.org/doc/html/rfc7231#autoid-37)
|
||||
[^4]: [RFC 7231 - POST](https://datatracker.ietf.org/doc/html/rfc7231#autoid-36)
|
43
Advanced Programming/projects/first/MR 1 Notes.md
Normal file
43
Advanced Programming/projects/first/MR 1 Notes.md
Normal file
@ -0,0 +1,43 @@
|
||||
---
|
||||
type: practical
|
||||
---
|
||||
## Genre
|
||||
- Cool, nice. We will extend.
|
||||
|
||||
## FileService
|
||||
- `importBooks` doesn't actually save books
|
||||
- CSV parsing might fail if there are commas in the data itself
|
||||
- Hardcoded CSV column names (just an observation, not necessarily bad)
|
||||
- File creation creates temp files without deleting them
|
||||
|
||||
## BookService
|
||||
- `createBook` doesn't ensure isbn uniqueness
|
||||
|
||||
## BookRepository
|
||||
- Our documentation is not updated. The class map cointains findByISBN.
|
||||
- Only 'isbn' is supported. Implement:
|
||||
- findByAttributes(BookAttributes attrs)
|
||||
- findByID(long pk)
|
||||
- deleteByAttributes
|
||||
- deleteByID
|
||||
|
||||
## BookAttributes
|
||||
- Every field should be private (@Data automatically adds gsetters)
|
||||
- Perhaps add data validation? Not necessary.
|
||||
|
||||
|
||||
## Book
|
||||
- Attributes can be null. Add null checks in getters and setters to avoid. We don't want null ptr exceptions
|
||||
|
||||
## BookController
|
||||
- Do not interact with repository directly. Go through service.
|
||||
|
||||
|
||||
## BookService
|
||||
- `createBook` returns true always, no matter what the status is
|
||||
- matchingAny is OR, false positives might be returned. Perhaps use matchingAll? Not sure about this.
|
||||
- `deleteBooksByAttribute` is missing
|
||||
|
||||
|
||||
|
||||
|
1715
Advanced Programming/projects/first/Specification.md
Normal file
1715
Advanced Programming/projects/first/Specification.md
Normal file
File diff suppressed because it is too large
Load Diff
101
Advanced Programming/projects/second/Fixing code smells.md
Normal file
101
Advanced Programming/projects/second/Fixing code smells.md
Normal file
@ -0,0 +1,101 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
tags:
|
||||
- excalidraw
|
||||
type: practical
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving'
|
||||
|
||||
|
||||
# Excalidraw Data
|
||||
## Text Elements
|
||||
%%
|
||||
## Drawing
|
||||
```compressed-json
|
||||
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=
|
||||
```
|
||||
%%
|
16
Advanced Programming/projects/second/Refactoring.canvas
Normal file
16
Advanced Programming/projects/second/Refactoring.canvas
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"nodes":[
|
||||
{"id":"0b575c52e89e5e7f","x":-868,"y":-500,"width":1018,"height":660,"color":"1","type":"group","label":"Problem"},
|
||||
{"id":"59984a2333620a30","type":"text","text":"Problem - Too much reused logic\n","x":-580,"y":-480,"width":320,"height":80},
|
||||
{"id":"4a3daa677e26d98e","x":-763,"y":-235,"width":250,"height":155,"type":"text","text":"`@Entity`s (Book, Review, Album) all have an `id` and an `attributes` field."},
|
||||
{"id":"189837e2bb3fcc18","x":-440,"y":-233,"width":250,"height":153,"type":"text","text":"Controllers and services for each entity perform almost identical operations."},
|
||||
{"id":"1144a58bdce0327e","x":-848,"y":15,"width":308,"height":125,"type":"text","text":"The `@Embeddable` attributes are also functionally the same, although with different values"},
|
||||
{"id":"5739ca50af3e054a","x":-120,"y":-235,"width":250,"height":117,"type":"text","text":"Updates to common functionality require changes in multiple places"}
|
||||
],
|
||||
"edges":[
|
||||
{"id":"2b2b795da278ff01","fromNode":"59984a2333620a30","fromSide":"bottom","toNode":"4a3daa677e26d98e","toSide":"top"},
|
||||
{"id":"2ea24f6cc0e66abd","fromNode":"59984a2333620a30","fromSide":"bottom","toNode":"189837e2bb3fcc18","toSide":"top"},
|
||||
{"id":"6b94289b63a6655a","fromNode":"4a3daa677e26d98e","fromSide":"bottom","toNode":"1144a58bdce0327e","toSide":"top"},
|
||||
{"id":"c4ea927674cd8e4d","fromNode":"59984a2333620a30","fromSide":"bottom","toNode":"5739ca50af3e054a","toSide":"top"}
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user