Goal: Another take-home challenge
- Overview
- Requirements
- Project Structure
- Howto Build and Run
- Screenshot
- Links
- Built with
- Code Snippet
- Continued development
- Useful resources
- Author
- Portfolio
This challenge delivers an application that consumes an external API endpoint. It is a RFC8288 compliant paginated endpoint to be consumed, returning a list of contacts and the pagination information via link header and should be built according to some specific requirements.
- The response from the endpoint should match the schema provided.
- Project structure and organization of your code: we want to see if your code follows good patterns, and separates concerns between controllers, services, and repositories.
- Capacity to follow good principles like Clean Code and SOLID.
- Capacity to use design patterns and knowledge about the chosen one(s) usage.
- Ability to consume other APIs and correctly handle pagination.
- Knowledge about the tools you decided to use.
- Ability to create smart tests to enhance your code quality.
Based on these, the app consumes services of another api -> Contacts API.
You can play with the app, visiting the link below after you build the app according to the instructions.
https://challenge.ferreiras.dev.br/swagger-ui/index.html
The app has been coded using Java 17, Spring Boot 3.3.4, Gradle, Javadoc, Spring Security, Spring JPA,
Spring Webflux, OpenAPI, JUnit, Mockito, MySQL, Docker and others.
Take a look at the video below to understand how I faced the challenge.
Short Video
- docs
- javadocs
- src
- main
- java
- br.dev.ferreiras.challenge
- contracts
- config
- controller
- handlers
- dto
- entity
- enums
- repository
- services
- exceptions
- br.dev.ferreiras.challenge
- resources
- certs
- test
- java
- br.dev.ferreiras.challenge
- controller
- service
- br.dev.ferreiras.challenge
- java
- MySQL Database: http://127.0.0.1:3306:challenge
- credentials available at classpath:db.properties
- profile active: dev or prod
- production socket:127.0.0.1:8097
- tweak a few knobs to get it up and running according to the instructions
provided at classpath:dockerBuild.sh or just in case you want ro run
locally go to {PWD}/challenge and run ./gradlew run, or check the video
url shown below.
- Live Site -> Click here ☁️ API Aggregator
import java.util.List;
/**
*
* @author ricardo@ferreiras.dev.br
* @version 1.1.10.23.01
* @since 1.0
*
*/
@RestController
@RequestMapping("api/v1")
public class ContactController {
private final ContactService contactService;
public ContactController(ContactService contactService) {
this.contactService = contactService;
}
@Operation(summary = "Fetch 20 contacts per page")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Get up to 20 contacts per page.",
content = {@Content(mediaType = "application/json",
schema = @Schema (implementation = ResponseContactsDto.class))}),
@ApiResponse(responseCode = "400", description = "Bad Request",
content = {@Content(mediaType = "application/json")}),
@ApiResponse(responseCode = "401", description = "Access Denied",
content = {@Content(mediaType = "application/json")}),
@ApiResponse(responseCode = "403", description = "FORBIDDEN",
content = {@Content(mediaType = "application/json")}),
@ApiResponse(responseCode = "404", description = "Resource not found!",
content = {@Content(mediaType = "application/json")})
})
@ResponseStatus(HttpStatus.OK)
@GetMapping("/contacts")
@PreAuthorize("hasAuthority('SCOPE_ROLE_ADMIN')")
public Mono<ResponseContactsDto> getContacts(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size
) {
return contactService.makeApiRequest()
.bodyToMono(ResponseContactsDto.class);
}
}
- Unit Tests - done
- Subscriber Authentication - done
- Spring JWT-OAuth2 - done
- Records Pagination - done
- [https://spring.io/] Awesome Java framework!.
- [https://start.spring.io/] Handy startup tool.
- [https://mvnrepository.com/]
