spring into spring: basics, API, beans
Tags: beginners, springboot, api, learning
Published: 2024-04-23 17:43:22

It’s Week 9 of bootcamp, and it’s all about APIs, Spring, and beans. As the teacher drones on and we frantically try to keep up, memes about beans pop up in our #fun-chat Slack. Our first day learning about them, I swore I never even wanted to see beans again in the grocery store. 

Now, after four and a half days of instruction and a 2-day group project on building the backend to handle calls to endpoints for managing sports leagues, I think I no longer have a beef with beans. 😉  Let’s spring into Spring, API, and beans and summarize some high-level basic concepts (which I myself struggled to get, so hopefully this can help other beginners too). You can read more detailed learnings in my project page [here](https://github.com/ashleyd480/league-app-jpa-spring). 


![Funny-Teacher](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u75hy9wio0lzmork16wi.gif)


## Table of Contents
1. 🌸 [API](https://dev.to/ashleyd480/spring-into-spring-basics-api-beans-1dbo#api)

2. 🌷 [Spring Basics](https://dev.to/ashleyd480/spring-into-spring-basics-api-beans-1dbo#spring-basics)

3. 🌼 [Beans Basics](https://dev.to/ashleyd480/spring-into-spring-basics-api-beans-1dbo#beans-basics-%F0%9F%AB%98)



---

## API 🌐
Communication happens between the web server and the application server via HTTP, typically facilitated by an API.

- REST API is an API that follows REST, a set of design principles for talking to backend where the client (i.e. web browser, mobile app, etc) and server are separate entities. 
- We can use the RESTful (rest compliant methods) of `Get` (retrieve), `Post` (create), `Put` (update), and  `Delete` http methods to access endpoints to retrieve and manipulate info. 
- Endpoints are URLs that clients use to interact with your application
For example, `Get http://localhost:8080/tournaments`  is  a REST call over HTTP to a specific endpoint.

### Example flow 
Let’s say a user visiting a website clicks on a button to get a list of tournaments.

1. A request sent to the application server via API through a REST call. The REST call itself will be a `Get` request with a specific endpoint, i.e. ` http://localhost:8080/tournaments`.
2. The server checks to see if that endpoint is in the RestController class. Once it finds the `getAll Tournaments` method in the Controller class, that method is then run. The @GetMappipng annotation makes that endpoint accessible)
3. Once the endpoint is found, data is then retrieved as JSON. 
4. That data is then sent back as JSON and then parsed into what the user can understand. 


![API Cartoon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmznx66bvxnkijdsxhst.jpg)

### Postman 
We use IntelliJ for coding and Maven is used to manage dependencies (which you can see through your `pom.xml`). Tomcat serves as our web application, and you define how you want to connect to your database through your `application.properties`. Postman helps test HTTP requests (and this is done through that localhost URL which allows you to test locally on your computer).

![Put Postman Call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xecz6w9oysi5184se3dw.png)

The above shows us testing the `Put` endpoint on updating the information on Tournaments with id of 1. Since the id is already provided, in the request body, we simply need to provide the name and team information, along with the updated value for either or both fields. (This simulates a user on a website trying to update tournament information.)

If you encounter an error 400 on Postman, it could indicate that you have missing or incorrect parameters, or that your data format is not in the correct format (i.e. the request body requires a list, but you didn't format it as such). 

---

## Spring Basics 🌱

Spring is a Java framework, and can also be used for building RESTful APIs. 
When working with databases, you can select: spring web, spring Data JPA, Lombok, PostgreSQL Driver as your dependencies when creating a new project. 


### 3 Layers 
We commonly use these 3 layers in Spring to manage data in a structured way as shown in the screenshot below (credit to our teacher for making it).

![Layers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kr5tp69bh3g966d0g7d.png)

- `Model`:  represents your entities or tables and are annotated with @Entity
Lombok allows you to use the `@Data`, `@AllArgsConstructor` and `@NoArgsConstructor` - allowing the framework to create the constructors, getters,and setters for you. Optionally, you can use `@Table` if your table name in the database is longer (i.e. `USA_Football_Tournaments` , but you would like to keep your class name short (i.e. `Tournaments`). 

- `Controller`: handles the web requests. The `@RestController` annotation tells Spring this controller to intercept http communication, and this is how the application would know what to do when an API call is sent back - and it looks for a method with the matching endpoint signature, checking the annotations (@GetMapping @PostMapping, @PutMapping, @DeleteMapping) and URL.

- `Repository`: interface that extends JpaRepository, which allows you to run common data operations, such as saving, finding, updating, and deleting records via `findAll`, `findById`, `save` and `deleteById`. The two find methods do return an Optional - which is a data type to represent that your search may or may not come up with something.  

```
iStudentRepository.findById(id).orElseThrow(()-> new RuntimeException("Course with id" + id +  " does not exist"));
```

For custom query methods, you can add @Query annotation and define the customer query logic with JPQL (example from my [project](https://github.com/ashleyd480/league-app-jpa-spring?tab=readme-ov-file#jpql)). 

---
## Beans Basics 🫘

### Dependency Injection
This is a design pattern that is a core feature of the Spring Framework, and it’s an example of Inversion of Control. Similar to Hollywood- where they say “Don’t call us, we call you”,  instead of the programmer invoking and managing methods, the framework calls the methods defined by the programmer. (This principle is also applied in how the RestController handles the HTTP requests vs the programmer worrying about having to invoke additional methods to do so.)

In Spring, beans are the objects managed by Spring’s IoC container and dependency injection is how the beans receive their dependencies. Say what? 🤨 

I’ve summarized the steps more simply below to help break down that understanding. 

### Lifecycle 

1. Upon application launch, Spring scans for classes that are candidates for becoming a bean by checking for annotations like @Component, @Service, @Repository, etc
2. Then it creates instances of those classes aka ‘beans’.
3. (These beans live as the application is running and go bye felicia once the app is terminated.)
4. Autowire tells Spring when there’s a dependency we need to inject - like say a Controller class depends on a Service class. In this example code block below, the `TeamController` class has a PostMapping /teams endpoint. The method is called in the `TeamController`, but then defined in the `TeamService` class.

```
@RestController
public class TeamController {

    @Autowired
    TeamService teamService;

   @PostMapping("/teams")
    public Team createTeam(@RequestBody Team team) {
        return teamService.addTeam(team);
    }

…
}
```

The method is called in the `TeamController`, but then defined in the `TeamService` class. In other words, that controller class depends on that service class.  It knows to inject the `TeamService` beans, because it scans for a bean with the type of `TeamService` (and if there were multiple of that type, it would filter out which one by checking for the `@Primary` annotation) That instance of bean is named `teamService`, and non-static methods are called on it.

Similarly, the Service class depends on its respective repository, hence the Autowire dependency injection. 

```
@Service
public class TeamService {
    @Autowired
    ITeamRepository iTeamRepository;
```

### Benefits
Beans allow for more flexibility. The screenshot below shows a hypothetical example where a Controller class can implement either a SQL or noSQL repository interface. 
If we hard code it (image on left), then if we decide to use a different repository implementation, this will require us to rewrite the code (and this can be even more problematic if your existing implementation is used in various places in the codebase). However, with beans dependency injections (image on right), we can easily just change the implementation by switching around the `@Primary` annotation. 


![Hard-Code Dependency vs With Beans](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qb5ftwmp96ls2wgq6qnm.png)