Skip to content

Commit

Permalink
Merge pull request #266 from trebol-ecommerce/feature/swagger-ui
Browse files Browse the repository at this point in the history
Feature/swagger UI
  • Loading branch information
bglamadrid authored Oct 5, 2024
2 parents 704cd38 + 0122ee6 commit e8ab736
Show file tree
Hide file tree
Showing 24 changed files with 229 additions and 68 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Conforming to API v3
### Added

- [Springdoc](https://springdoc.org) library, to enrich the project with two new features:
- Generation of an OpenAPI 3.0 spec file, akin to [the Trebol API](https://github.com/trebol-ecommerce/api)'s
- Generation of a [Swagger UI](https://swagger.io/tools/swagger-ui/) page and endpoint.

### Changed

#### Conforming to API v3

- Follow new specification for error messages
- Introduce new model class `AppError`
Expand Down Expand Up @@ -68,6 +76,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- All PUT,PATCH,DELETE,OPTIONS requests return 204
- Remove duplicated functionality endpoint `/public/checkout/result/{token}`
- Served the same purpose as `/public/receipt/{token}`
- Remove support for paths with leading slash
- For example, `/public/checkout/` is no longer accepted, only `/public/checkout`

## [v0.2.4] - 2024-08-28

Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@
<artifactId>unirest-java</artifactId>
<version>${unirest.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>

<!-- Testing -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package org.trebol.api.controllers;

import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
Expand All @@ -46,6 +48,7 @@

@RestController
@RequestMapping("/access")
@Tag(name = "User Accounts")
@PreAuthorize("isAuthenticated()")
public class AccessController {
private final AuthorizationHeaderParserService<Claims> jwtClaimsParserService;
Expand All @@ -66,7 +69,8 @@ public AccessController(
this.regexMatcherService = regexMatcherService;
}

@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List authorized API routes")
public AuthorizedAccessPojo getApiRoutesAccess(@RequestHeader HttpHeaders requestHeaders)
throws UsernameNotFoundException, IllegalStateException {
UserDetails userDetails = this.getUserDetails(requestHeaders);
Expand All @@ -79,7 +83,8 @@ public AuthorizedAccessPojo getApiRoutesAccess(@RequestHeader HttpHeaders reques
.build();
}

@GetMapping({"/{apiRoute}", "/{apiRoute}/"})
@GetMapping("/{apiRoute}")
@Operation(summary = "List authorized access to API route")
public AuthorizedAccessPojo getApiResourceAccess(
@RequestHeader HttpHeaders requestHeaders,
@PathVariable String apiRoute)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package org.trebol.api.controllers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -36,6 +38,7 @@

@RestController
@RequestMapping("/account/profile")
@Tag(name = "User Accounts")
@PreAuthorize("isAuthenticated()")
public class AccountProfileController {
private final ProfileService userProfileService;
Expand All @@ -47,14 +50,16 @@ public AccountProfileController(
this.userProfileService = userProfileService;
}

@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "View stored profile information")
public PersonPojo getProfile(Principal principal)
throws EntityNotFoundException {
String username = principal.getName();
return userProfileService.getProfileFromUserName(username);
}

@PutMapping({"", "/"})
@PutMapping
@Operation(summary = "Replace stored profile information")
public void updateProfile(Principal principal, @RequestBody PersonPojo newProfile)
throws EntityNotFoundException, BadInputException {
String username = principal.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package org.trebol.api.controllers;

import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -40,6 +42,7 @@

@RestController
@RequestMapping("/data/billing_types")
@Tag(name = "Params management")
public class DataBillingTypesController
extends DataGenericController<BillingTypePojo, BillingType> {

Expand All @@ -54,7 +57,8 @@ public DataBillingTypesController(
}

@Override
@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List billing types.")
public DataPagePojo<BillingTypePojo> readMany(@RequestParam Map<String, String> allRequestParams) {
return super.readMany(allRequestParams);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package org.trebol.api.controllers;

import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
Expand All @@ -45,6 +47,7 @@

@RestController
@RequestMapping("/data/customers")
@Tag(name = "People management")
@PreAuthorize("isAuthenticated()")
public class DataCustomersController
extends DataCrudGenericController<PersonPojo, Customer> {
Expand All @@ -60,14 +63,16 @@ public DataCustomersController(
}

@Override
@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List customers.")
@PreAuthorize("hasAuthority('customers:read')")
public DataPagePojo<PersonPojo> readMany(@RequestParam Map<String, String> allRequestParams) {
return super.readMany(allRequestParams);
}

@Override
@PostMapping({"", "/"})
@PostMapping
@Operation(summary = "Register new customer.")
@PreAuthorize("hasAuthority('customers:create')")
@ResponseStatus(CREATED)
public void create(@Valid @RequestBody PersonPojo input)
Expand All @@ -76,7 +81,8 @@ public void create(@Valid @RequestBody PersonPojo input)
}

@Override
@PutMapping({"", "/"})
@PutMapping
@Operation(summary = "Replace customers data.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('customers:update')")
public void update(@Valid @RequestBody PersonPojo input, @RequestParam Map<String, String> requestParams)
Expand All @@ -85,7 +91,8 @@ public void update(@Valid @RequestBody PersonPojo input, @RequestParam Map<Strin
}

@Override
@DeleteMapping({"", "/"})
@DeleteMapping
@Operation(summary = "Deregister customers.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('customers:delete')")
public void delete(Map<String, String> requestParams)
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/org/trebol/api/controllers/DataImagesController.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package org.trebol.api.controllers;

import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand Down Expand Up @@ -54,6 +56,7 @@

@RestController
@RequestMapping("/data/images")
@Tag(name = "Images management")
@PreAuthorize("isAuthenticated()")
public class DataImagesController
extends DataCrudGenericController<ImagePojo, Image> {
Expand All @@ -69,14 +72,16 @@ public DataImagesController(
}

@Override
@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List image links data.")
@PreAuthorize("hasAuthority('images:read')")
public DataPagePojo<ImagePojo> readMany(@RequestParam Map<String, String> allRequestParams) {
return super.readMany(allRequestParams);
}

@Override
@PostMapping({"", "/"})
@PostMapping
@Operation(summary = "Define new image links.")
@ResponseStatus(CREATED)
@PreAuthorize("hasAuthority('images:create')")
public void create(@Valid @RequestBody ImagePojo input)
Expand All @@ -85,7 +90,8 @@ public void create(@Valid @RequestBody ImagePojo input)
}

@Override
@PutMapping({"", "/"})
@PutMapping
@Operation(summary = "Replace image links data.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('images:update')")
public void update(@Valid @RequestBody ImagePojo input, @RequestParam Map<String, String> requestParams)
Expand All @@ -94,7 +100,8 @@ public void update(@Valid @RequestBody ImagePojo input, @RequestParam Map<String
}

@Override
@PatchMapping({"", "/"})
@PatchMapping
@Operation(summary = "Update parts of image links data.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('images:update')")
public void partialUpdate(
Expand All @@ -105,7 +112,8 @@ public void partialUpdate(
}

@Override
@DeleteMapping({"", "/"})
@DeleteMapping
@Operation(summary = "Remove image links.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('images:delete')")
public void delete(@RequestParam Map<String, String> requestParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package org.trebol.api.controllers;

import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -41,6 +43,7 @@

@RestController
@RequestMapping("/data/order_statuses")
@Tag(name = "Params management")
@PreAuthorize("isAuthenticated()")
public class DataOrderStatusesController
extends DataGenericController<OrderStatusPojo, OrderStatus> {
Expand All @@ -56,7 +59,8 @@ public DataOrderStatusesController(
}

@Override
@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List order statuses.")
@PreAuthorize("hasAuthority('order_statuses:read')")
public DataPagePojo<OrderStatusPojo> readMany(@RequestParam Map<String, String> allRequestParams) {
return super.readMany(allRequestParams);
Expand Down
27 changes: 19 additions & 8 deletions src/main/java/org/trebol/api/controllers/DataOrdersController.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;
Expand Down Expand Up @@ -61,6 +63,7 @@

@RestController
@RequestMapping("/data/orders")
@Tag(name = "Orders management")
@PreAuthorize("isAuthenticated()")
public class DataOrdersController
extends DataCrudGenericController<OrderPojo, Order> {
Expand All @@ -83,7 +86,8 @@ public DataOrdersController(
}

@Override
@GetMapping({"", "/"})
@GetMapping
@Operation(summary = "List orders.")
@PreAuthorize("hasAuthority('orders:read')")
public DataPagePojo<OrderPojo> readMany(@RequestParam Map<String, String> allRequestParams) {
if (allRequestParams!=null) {
Expand All @@ -106,7 +110,8 @@ public DataPagePojo<OrderPojo> readMany(@RequestParam Map<String, String> allReq
}

@Override
@PostMapping({"", "/"})
@PostMapping
@Operation(summary = "Create new orders.")
@ResponseStatus(CREATED)
@PreAuthorize("hasAuthority('orders:create')")
public void create(@Valid @RequestBody OrderPojo input)
Expand All @@ -115,7 +120,8 @@ public void create(@Valid @RequestBody OrderPojo input)
}

@Override
@PutMapping({"", "/"})
@PutMapping
@Operation(summary = "Replace orders data.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('orders:update')")
public void update(@Valid @RequestBody OrderPojo input, @RequestParam Map<String, String> requestParams)
Expand All @@ -124,7 +130,8 @@ public void update(@Valid @RequestBody OrderPojo input, @RequestParam Map<String
}

@Override
@PatchMapping({"", "/"})
@PatchMapping
@Operation(summary = "Update parts of orders data.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('orders:update')")
public void partialUpdate(
Expand All @@ -135,15 +142,17 @@ public void partialUpdate(
}

@Override
@DeleteMapping({"", "/"})
@DeleteMapping
@Operation(summary = "Remove orders.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('orders:delete')")
public void delete(@RequestParam Map<String, String> requestParams)
throws EntityNotFoundException {
super.delete(requestParams);
}

@PostMapping({"/confirmation", "/confirmation/"})
@PostMapping("/confirmation")
@Operation(summary = "Confirm a pending order.")
@ResponseStatus(NO_CONTENT)
@PreAuthorize("hasAuthority('orders:update')")
public void confirmSell(@RequestBody OrderPojo sell)
Expand All @@ -155,7 +164,8 @@ public void confirmSell(@RequestBody OrderPojo sell)
}
}

@PostMapping({"/rejection", "/rejection/"})
@PostMapping("/rejection")
@Operation(summary = "Reject a pending order.")
@PreAuthorize("hasAuthority('orders:update')")
public void rejectSell(@RequestBody OrderPojo sell)
throws BadInputException, MailingServiceException {
Expand All @@ -165,7 +175,8 @@ public void rejectSell(@RequestBody OrderPojo sell)
}
}

@PostMapping({"/completion", "/completion/"})
@PostMapping("/completion")
@Operation(summary = "Mark an order as completed.")
@PreAuthorize("hasAuthority('orders:update')")
public void completeSell(@RequestBody OrderPojo sell)
throws BadInputException, MailingServiceException {
Expand Down
Loading

0 comments on commit e8ab736

Please sign in to comment.