# Containerized Spring Boot + MySQL +Open API Docker REST API implementation

REST API implementation is mostly the defacto standard in the industry to develop any API. Mostly REST APIs are used by most developers. Cloud-native development makes it compulsory to develop containerized, portable applications. In this article, you are going learn how to create spring boot, Open API and MySQL REST API with a docker container.

### Tech Stack:

* Spring Boot
    
* Java 11
    
* Gradle
    
* MySQL
    
* Docker
    
* Open API documentation
    
* REST API
    

Let us first start with the implementation and understand the model of the database, here we have a simple database structure that contains the SQL script of two table students and classrooms where the student is part.

### SQL Script:

```sql
USE student_classroom;

INSERT INTO classrooms (name, capacity) VALUES ('Mathematics', 30);
INSERT INTO classrooms (name, capacity) VALUES ('History', 25);

INSERT INTO students (name, age, email, classroom_id) VALUES ('John Doe', 20, 'john.doe@example.com', 1);
INSERT INTO students (name, age, email, classroom_id) VALUES ('Jane Smith', 19, 'jane.smith@example.com', 2);
```

## Setup:

Set up an application using start.spring.io or using any of your editors. I am using VSCode editor. First, create a new Spring Boot project using the Spring Initializr, which is a web-based tool that helps you generate the basic structure of your project. You can choose to use Maven or Gradle as your build tool, depending on your preference. Here in this example we choose Gradle.

Let us check the code file one by one.

### application.properties:

```bash
spring.datasource.url=jdbc:mysql://localhost:3306/school
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
```

### Define the data model:

Create the data model for the student and classroom entities using JPA annotations. Here's an example:

```java
@Entity
@Table(name = "students")
public class Student {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
   private String name;
   private int age;
   private String email;
   
   @ManyToOne
   @JoinColumn(name = "classroom_id")
   private Classroom classroom;
   
   // getters and setters
}

@Entity
@Table(name = "classrooms")
public class Classroom {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
   private String name;
   private int capacity;
   // getters and setters
}
```

### Create the repository:

Create the repository interface for the student and classroom entities that extends JpaRepository. Here's an example:

```java
public interface StudentRepository extends JpaRepository<Student, Long> {
}

public interface ClassroomRepository extends JpaRepository<Classroom, Long> {
}
```

### Create the REST controller:

Create the REST controller that handles HTTP requests and responses for the student and classroom entities. Here's an example:

```java
@RestController
@RequestMapping("/api")
public class SchoolController {
   @Autowired
   private StudentRepository studentRepository;
   @Autowired
   private ClassroomRepository classroomRepository;
   
   @GetMapping("/students")
   public List<Student> getAllStudents() {
       return studentRepository.findAll();
   }
   
   @PostMapping("/students")
   public Student createStudent(@RequestBody Student student) {
       return studentRepository.save(student);
   }
   
   @GetMapping("/classrooms")
   public List<Classroom> getAllClassrooms() {
       return classroomRepository.findAll();
   }
   
   @PostMapping("/classrooms")
   public Classroom createClassroom(@RequestBody Classroom classroom) {
       return classroomRepository.save(classroom);
   }
}
```

### Create the Dockerfile:

Create a Dockerfile that defines the environment and dependencies for your application. Simple docker file, for production definitely you can follow best practices.

```bash
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY target/school-0.0.1-SNAPSHOT.jar school.jar
ENTRYPOINT ["java","-jar","/school.jar"]
```

### Create build.gradle file:

Create the build gradle file, which is helping us to define the build instructions. Here's an example:

```java
plugins {
    id 'org.springframework.boot' version '2.6.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
java.sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'mysql:mysql-connector-java'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.3'
    implementation 'org.springdoc:springdoc-openapi-data-rest:1.6.3'
}

test {
    useJUnitPlatform()
}

bootRun {
    args = ['--spring.profiles.active=dev']
}
```

### Create Application java file:

The application java file is an entry point for the application to start. Here's an example:

```java
@SpringBootApplication
@OpenAPIDefinition(
  info = @Info(
    title = "Student and Classroom API",
    version = "1.0",
    description = "API for managing students and classrooms"
  )
)
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
```

### Run the application:

If you want to run the application using the docker file only then run the below command and validate.

```bash
docker build -t school .
docker run -p 8080:8080 school
```

### Docker compose:

Docker compose file which contains both MySQL database and spring application container to run together.

```bash
version: '3.9'

services:
  mysql:
    image: mysql:8.0.28
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: student_classroom
    ports:
      - "3306:3306"
    volumes:
      - ./mysql-data:/var/lib/mysql
      - ./mysql-scripts:/docker-entrypoint-initdb.d
  myapp:
    build:
      context: .
      dockerfile: Dockerfile
    image: myapp
    container_name: myapp
    depends_on:
      - mysql
    ports:
      - "8080:8080"
```

Run docker-compose using the below command

```bash
docker-compose up
```

Now enjoy the application by hitting the REST endpoint using the postman or curl command.

This will start the MySQL container and the Spring Boot app container. You should see logs from both containers in the terminal.

Once the containers are running, you can access the Spring Boot app by opening a web browser and navigating to [`http://localhost:8080`](http://localhost:8080). If everything is working correctly, you should see the default Spring Boot landing page.

I hope this helps, you!!

**More such articles:**

[https://medium.com/techwasti](Link)

[https://www.youtube.com/channel/UCiTaHm1AYqMS4F4L9zyO7qA](Link)

[https://www.techwasti.com/](Link)

\==========================\*\*=========================

**If this article adds any value to you then please clap and comment.**

**Let’s connect on** [**Stackoverflow**](http://stackoverflow.com/users/3187349/maheshwar-ligade)**,** [**LinkedIn**](https://in.linkedin.com/in/maheshwar-ligade-14447841)**, &** [**Twitter**](https://twitter.com/MaheshwarLigade)**.**
