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

Feature/swagger UI #266

Merged
merged 4 commits into from
Oct 5, 2024
Merged
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
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
Loading