API structure consists of such modules:
this module contains project controllers. Here example is an example of api-impl structure:
package com.knubisoft.api.impl; import com.knubisoft.api.dto.GenericApiResponse; import com.knubisoft.api.dto.JwtTokensResponse; import com.knubisoft.api.dto.LoginRequest; import com.knubisoft.api.spec.LoginAPI; import com.knubisoft.service.LoginService; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @RequiredArgsConstructor @RestController public class LoginAPIImpl implements LoginAPI { private final LoginService loginService; @Override public ResponseEntity<GenericApiResponse<JwtTokensResponse>> login(@Valid final LoginRequest requestBody) { final JwtTokensResponse result = loginService.login(requestBody.getUsername(), requestBody.getPassword()); return ResponseEntity.ok(new GenericApiResponse<>(result)); } } |
this module consists of xml description of enpoints, controllers, enums, dto and etc. Also generated API interfaces
About xml description you can find details here
Also we have another(todo refactor) spec module which is located in a different place and does not contain business logic
<controller xmlns="http://www.knubisoft.com/api/schema/controller"> <overview> <description> Login API </description> </overview> <public> <!-- Login API flow --> <include value="login"/> </public> </controller> |
<endpoint xmlns="http://www.knubisoft.com/api/schema/endpoint"> <swagger> <operationId>login</operationId> <summary>Logging in</summary> <description>Logging in with user credentials</description> <tags> <tag>Login</tag> </tags> </swagger> <responses> <_200>Success HTTP response from API with HTTP body</_200> <_404>Accepted HTTP call request but requested object is NOT FOUND</_404> </responses> <post> <response include="jwtTokensResponse.xml"/> <request include="loginRequest.xml"/> </post> </endpoint> |
package com.knubisoft.api.spec; import com.fasterxml.jackson.core.type.TypeReference; import com.knubisoft.api.dto.GenericApiResponse; import com.knubisoft.api.dto.JwtTokensResponse; import com.knubisoft.api.dto.LoginRequest; import com.knubisoft.api.spec.stub.StubFactory; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.annotation.Generated; import javax.validation.Valid; @Validated @Generated(value = "com.knubisoft.api.generator.Main", date = "2022-08-16T14:48:12.549Z") @RequestMapping("/api/v1/login") public interface LoginAPI { @Operation( summary = "Logging in", description = "Logging in with user credentials", tags = {"Login"} ) @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "Success HTTP response from API with HTTP body"), @ApiResponse( responseCode = "404", description = "Accepted HTTP call request but requested object is NOT FOUND") } ) @RequestMapping( consumes = "application/json", produces = "application/json", method = RequestMethod.POST) default ResponseEntity<GenericApiResponse<JwtTokensResponse>> login( @Valid @RequestBody LoginRequest requestBody) { return ResponseEntity.ok(StubFactory.produce(new TypeReference<GenericApiResponse<JwtTokensResponse>>(){ })); } } |
Dto module consists of generated classes(requests/responses and enums) that were described in spec module
Here is an example: