Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

00 update readme 2022 #6

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
# RestfullAPIs-With-Spring-Boot-2022
RestfullApis With Spring Boot 2022

Spring boot from scratch 2022.


# Technologies .
<div style="display:inline_block"><br/>
<img align="center" alt="java" src="https://img.shields.io/badge/Java-ED8B00?style=for-the-badge&logo=java&logoColor=white"/>
<img align="center" alt="spring" src="https://img.shields.io/badge/Spring-6DB33F?style=for-the-badge&logo=spring&logoColor=white"/>
<img align="center" alt="mysql" src="https://img.shields.io/badge/MySQL-00000F?style=for-the-badge&logo=mysql&logoColor=white"/>
<img align="center" alt="mongo" src="https://img.shields.io/badge/MongoDB-4EA94B?style=for-the-badge&logo=mongodb&logoColor=white"/>
</div>

# Implementations

1-Flyway Migration
2-Content Negotiation
3-Hateoas(Hypermedia as the engine of Application State)
4-Swagger
5-Cors(cross origin resource sharing)
6-Spring Security(Authentication with JWT)
7-Docker,Prometheus,Grafana
8-Pipeline CI/CD at AWS with Github Actions
9-Rest Assured ,Testcontainers, and JUnit 5

37 changes: 37 additions & 0 deletions data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
create table if not exists tb_persons
(
id int auto_increment
primary key,
address varchar(255) null,
email varchar(40) not null,
first_name varchar(255) not null,
gender varchar(255) null,
last_name varchar(200) not null,
constraint UK_ksrgjyqcn6cmmrsug93j7fdva
unique (email)
)engine=Innodb default charset=utf8;

insert into tb_persons ( address, email, first_name, gender, last_name)
values ('Maia Address','manuel@outlook.pt','manuel','MALE','lucas');

VALUES ('Benfica Lisbon', 'augusto@gmail.com', 'augusto', 'MALE', 'texeira');
INSERT INTO tb_persons (address, email, first_name, gender, last_name)
VALUES ('Street Amesterdam 123', 'tugcesenturk@gmail.com', 'tugce', 'FEMALE', 'senturky');
create table tb_persons
(
id int auto_increment
primary key,
address varchar(255) null,
email varchar(40) not null,
first_name varchar(255) not null,
gender varchar(255) null,
last_name varchar(200) not null,
constraint UK_ksrgjyqcn6cmmrsug93j7fdva
unique (email)
);

INSERT INTO tb_persons ( address, email, first_name, gender, last_name) VALUES ( 'Rua Luz Soriano Porto', 'vanilson@gmail.com', 'vanilson', 'MALE', 'wayne');
INSERT INTO tb_persons ( address, email, first_name, gender, last_name) VALUES ( 'Street Amesterdam', 'tugce@gmail.com', 'tugce', 'FEMALE', 'senturk');
INSERT INTO tb_persons ( address, email, first_name, gender, last_name) VALUES ( 'mexico ', 'rick@gmail.com', 'Rick', 'OTHER', 'Renner');
INSERT INTO tb_persons ( address, email, first_name, gender, last_name) VALUES ( null, 'rui@gmail.com', 'Rui', 'MALE', 'Renato');
INSERT INTO tb_persons ( address, email, first_name, gender, last_name) VALUES ( 'Maia Address', 'manuel@outlook.pt', 'manuel', 'MALE', 'lucas');
42 changes: 32 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,35 @@
<name>restfullapis_with_spring_boot_2022</name>
<description>Restfull APIs With Spring Boot 2022</description>
<properties>
<java.version>17</java.version>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Micrometer Prometheus registry -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.12.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
Expand All @@ -49,6 +63,14 @@
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand All @@ -59,11 +81,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package traineer.vanilson.restfullapis_with_spring_boot_2022.configuration;

import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import traineer.vanilson.restfullapis_with_spring_boot_2022.serialization_converter.YamlJacksonTwoHttpMessageConverter;

import java.util.List;

@Component
public class WebConfig implements WebMvcConfigurer {
private static final MediaType MEDIA_TYPE_APPLICATION_YML = MediaType.valueOf("application/x-yaml");


@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// via query param http://localhost:8080//api/v1/person?mediaType=xml

/*configurer.favorParameter(true)
.parameterName("mediaType")
.ignoreAcceptHeader(true)
.useRegisteredExtensionsOnly(false)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML);*/

// via header param http://localhost:8080//api/v1/person
// change header in postman with Accept (key) -Application/xml or json value

configurer.favorParameter(false)
.ignoreAcceptHeader(false)
.useRegisteredExtensionsOnly(false)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("x-yaml", MEDIA_TYPE_APPLICATION_YML);
}

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new YamlJacksonTwoHttpMessageConverter());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import traineer.vanilson.restfullapis_with_spring_boot_2022.exceptions.PersonNotFoundException;
import traineer.vanilson.restfullapis_with_spring_boot_2022.persistence.model.Person;
import traineer.vanilson.restfullapis_with_spring_boot_2022.services.PersonService;
import traineer.vanilson.restfullapis_with_spring_boot_2022.utils.MediaType;

import java.util.List;
import java.util.Optional;
Expand All @@ -20,25 +21,47 @@ public class PersonController {
private final PersonService personService;


@GetMapping(value = "/person")
@GetMapping(value = "/person",
produces = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML
})
public ResponseEntity<List<Person>> listAllPersons() throws IllegalAccessException {
return ResponseEntity.ok(Optional.of(personService.findAllPersons())
.orElseThrow(IllegalAccessException::new));
}

@GetMapping(value = "/person/{id}")
@GetMapping(value = "/person/{id}",
produces = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML
}
)
public ResponseEntity<Person> listAllPersonsById(@PathVariable(name = "id") Integer id) {
return ResponseEntity.ok(personService.findById(id));

}

@PostMapping(value = "/person/createNewPerson")
@PostMapping(value = "/person/createNewPerson",
produces = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML},
consumes = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML}
)
public ResponseEntity<Person> createNewPerson(@RequestBody Person person) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(personService.createNewPerson(person));
}

@PutMapping(value = "/person/update/{id}")
@PutMapping(value = "/person/update/{id}",
produces = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML},
consumes = {MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML,
MediaType.APPLICATION_YML})
public ResponseEntity<Person> updatePerson(@RequestBody Person person,
@PathVariable(value = "id") Integer id) {
if (person.getId().equals(id)) return ResponseEntity.ok(personService
Expand All @@ -47,5 +70,15 @@ public ResponseEntity<Person> updatePerson(@RequestBody Person person,
id + " was not founded in list");
}

@DeleteMapping(value = "/person/delete/{id}")
public ResponseEntity<Object> deleteParkingSpotById(@PathVariable(value = "id") int id) {
Person person = personService.findById(id);
if (person.getId().equals(id)) {
personService.deletePerson(id);
return ResponseEntity.status(HttpStatus.OK).body(" Person id deleted with successfully ");
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Person with id " + id + " was not found");
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ Content-Type: application/json
}

###
DELETE http://localhost:8080/api/v1/person/delete/5

###
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,8 @@ public class Person implements Serializable {
unique = true,
length = 40)
private String email;
@Column(name = "address",
nullable = false,
length = 40)
private String address;
@Enumerated(EnumType.STRING)
@Column(name = "gender",
nullable = false
)
private Gender gender;

public Person(String firstName, String lastName, String email, String address, Gender gender) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package traineer.vanilson.restfullapis_with_spring_boot_2022.serialization_converter;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;

public class YamlJacksonTwoHttpMessageConverter extends AbstractJackson2HttpMessageConverter {
public YamlJacksonTwoHttpMessageConverter() {
super(
new YAMLMapper()
.setSerializationInclusion(
JsonInclude.Include.NON_NULL),
MediaType.parseMediaType("application/x-yaml"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package traineer.vanilson.restfullapis_with_spring_boot_2022.utils;


public class MediaType {

public static final String APPLICATION_XML = "application/xml";
public static final String APPLICATION_JSON = "application/json";
public static final String APPLICATION_YML = "application/x-yaml";
}
33 changes: 10 additions & 23 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
#spring.datasource.url=jdbc:mysql://localhost:3306/testing_junit_2022
#spring.datasource.username=admin
#spring.datasource.password=
#spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
#spring.jpa.show-sql=true
#spring.jpa.hibernate.ddl-auto=update
#spring.jpa.properties.hibernate.format_sql=true
#server.error.include-message=always
#spring.flyway.baselineOnMigrate=true
#spring.flyway.fail-on-missing-locations=true
#spring.flyway.locations=classpath:db/migration
#spring.flyway.schemas=public
#spring.flyway.enabled=true
#spring.flyway.baseline-on-migrate=true
#
#management.endpoints.web.exposure.include=health,info,prometheus,metrics
#logging.level.org.hibernate.SQL=DEBUG
#logging.level.org.hibernate.type=TRACE
#
#
#flyway.url=jdbc:mariadb://localhost:3307/testing_junit_2022
#flyway.user=root
#flyway.password=mypass
spring.datasource.url=jdbc:mysql://localhost:3306/flyway_migrations_2022
spring.datasource.username=admin
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.format_sql=true
server.error.include-message=always
management.endpoints.web.exposure.include=health,info,prometheus,metrics
server.port=8000
18 changes: 9 additions & 9 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/testing_junit_2022?useTimezone=true&serverTimezone=UTC
username: admin
password:
jpa:
hibernate:
ddl-auto: update
#spring:
# datasource:
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/testing_junit_2022?useTimezone=true&serverTimezone=UTC
# username: admin
# password:
# jpa:
# hibernate:
# ddl-auto: update
12 changes: 12 additions & 0 deletions src/main/resources/db/migration/V1__create_person_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
create table if not exists tb_persons
(
id int auto_increment primary key,
first_name varchar(255) not null,
last_name varchar(200) not null,
email varchar(40) not null,
address varchar(255) null,
gender varchar(255) null,
constraint UK_ksrgjyqcn6cmmrsug93j7fdva
unique (email)
);

13 changes: 13 additions & 0 deletions src/main/resources/db/migration/V2__insert_person_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO tb_persons (first_name, last_name, email, address, gender)
VALUES ('augusto', 'texeira', 'augusto@gmail.com', 'São Paulo', 'MALE');
INSERT INTO tb_persons (first_name, last_name, email, address, gender)
VALUES ('ana', 'arneth', 'anato@gmail.com', 'Baia', 'FEMALE');
INSERT INTO tb_persons (first_name, last_name, email, address, gender)
VALUES ('gizem', 'anas', 'gizem@gmail.com', 'Istanbul', 'FEMALE');
INSERT INTO tb_persons (first_name, last_name, email, address, gender)
VALUES ('vanilson', 'wayne', 'vanilson@gmail.com', 'Rua Luz Soriano Porto', 'MALE'),
('tugce', 'senturk', 'tugce@gmail.com', 'Street Amesterdam', 'FEMALE'),
('Rick', 'Renner', 'rick@gmail.com', 'mexico ', 'OTHER'),
('Rui', 'Renato', 'rui@gmail.com', null, 'MALE'),
('Maria', 'Madalena', 'maria@gmail.com', null, 'FEMALE');