From 59015d22f7edc9ed5c5cacd4801c503119d872b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Er=C5=91s?= Date: Thu, 31 Oct 2024 21:10:21 +0100 Subject: [PATCH] readme fixes --- README.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1350405..c0a5114 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,82 @@ # Kappa - OpenAPI validator for Java and JVM projects -This project is a successor of the [archived openapi4j](https://github.com/openapi4j/openapi4j) project. +This project is a successor (permanent fork) of the [archived openapi4j](https://github.com/openapi4j/openapi4j) project. Kappa can be used to validate HTTP requests and responses against OpenAPI 3.1 definitions. Under the hood ist uses the [erosb/json-sKema](https://github.com/erosb/json-sKema) library for JSON Schema validation. -## Modules +## Validating incoming HTTP requests -* [Parser](openapi-parser) allows the (de-)serialization and manipulation of the schema and its validation. -* [Schema validator](openapi-schema-validator) allows the validation of data against a given schema. -* [Request validator](openapi-operation-validator) is high level module to manage validation for requests and/or responses against operations. More details in the related project. -* [Request adapters](openapi-operation-adapters) is the repository of specific adapters to wrap requests and responses. +If you want to validate the HTTP requests received by a Spring Boot service, you can do it by implementing +a simple `Filter` and intercepting incoming requests against your OpenAPI descriptions. -## Versioning and compatibility - -All modules follow the [Semantic Versioning 2.0.0](https://semver.org) and are aligned on each release even there's no changes. +### Installation - Maven ```xml - com.github.erosb.kappa - openapi-[module] + com.github.erosb + kappa-servlet-adapter + 2.0.0-RC6 + +``` + +### Add a filter to validate the request + +```java + +public class OpenApiBackedRequestValidationFilter implements Filter { + // reading the OpenAPI description of our API + private final OpenApi3 api = new OpenApi3Parser().parse(getClass().getResource("/openapi/pets-api.yaml"), false); + + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException { + HttpServletRequest httpReq = (HttpServletRequest) req; + HttpServletResponse httpResp = (HttpServletResponse) resp; + + try { + + // we need to wrap the original request instance into a MemoizingServletRequest, + // since we will need to parse the request body twice: once for the OpenAPI-validation + // and once for the jackson parsing. + // basic HttpServletRequests cannot be read twice, hence we use the MemoizingServletRequest shipped with Kappa + // more here: https://www.baeldung.com/spring-reading-httpservletrequest-multiple-times + MemoizingServletRequest memoizedReq = new MemoizingServletRequest(httpReq); + + // Kappa can understand different representations of HTTP requests and responses + // here we use the Servlet API specific adapter of Kappa, to get a Kappa Request instance + // which wraps a HttpServletRequest + JakartaServletRequest jakartaRequest = JakartaServletRequest.of(memoizedReq); + + // we do the validation + new RequestValidator(api).validate(jakartaRequest); + + // if no request validation error was found, we proceed with the request execution + chain.doFilter(memoizedReq, httpResp); + + } catch (ValidationException ex) { + // if the request validation failed, we represents the validation failures in a simple + // json response and send it back to the client + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode respObj = objectMapper.createObjectNode(); + ArrayNode itemsJson = objectMapper.createArrayNode(); + ex.results().forEach(item -> { + ObjectNode itemJson = objectMapper.createObjectNode(); + itemJson.put("dataLocation", item.describeInstanceLocation()); + itemJson.put("schemaLocation", item.describeSchemaLocation()); + itemJson.put("message", item.message); + itemsJson.add(itemJson); + }); + respObj.put("errors", itemsJson); + httpResp.setStatus(400); + httpResp.getWriter().print(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(respObj)); + } + } +} + + ``` ## Supported versions @@ -41,10 +95,11 @@ We accept Pull Requests via GitHub. There are some guidelines which will make ap ## License -Kappa and all the modules are released under the Apache 2.0 license. See [LICENSE](https://github.com/openapi4j/openapi4j/blob/master/LICENSE.md) for details. +Kappa is released under the Apache 2.0 license. See [LICENSE](https://github.com/openapi4j/openapi4j/blob/master/LICENSE.md) for details. ## Contributor notes Release to local maven repo: `./gradlew build publishToMavenLocal` + Release to maven central: `./gradlew build publishToSonatype closeAndReleaseSonatypeStagingRepository`