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

Form configuration page documentation update #125

Merged
merged 1 commit into from
Aug 18, 2022
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
6 changes: 3 additions & 3 deletions nrich-form-configuration-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

## Overview

Contains classes that represent the API (interfaces, data classes and requests) for `nrich-form-configuration` module. The interfaces have default implementations provided
in `nrich-form-configuration` module but users can provide their own implementations. Unless some overriding is required only classes from this module should be used directly, other configuration
should be provided through property files.
This module contains classes that represent the API (interfaces and data classes) for [`nrich-form-configuration`](../nrich-form-configuration/README.md) module.
Default implementations are provided in [`nrich-form-configuration`](../nrich-form-configuration/README.md) module, but users can provide their own implementations.
If no overriding is required, only classes from this module should be used.
71 changes: 45 additions & 26 deletions nrich-form-configuration-spring-boot-starter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

## Overview

Spring Boot starter for `nrich-form-configuration` module. The purpose of `nrich-form-configuration` is converting constraints defined on the server side in a form that can be used on the client side
to apply the same constraints on the client thus avoiding repeating constraints on both server and client side. Starter module provides a `@Configuration`
class (`NrichFormConfigurationAutoConfiguration`) with default configuration of `nrich-form-configuration` module (while allowing for overriding with conditional annotations)
and a `@ConfigurationProperties` class (`NrichFormConfigurationProperties`) with default configured values and does automatic registration through `spring.factories`.
This module is a Spring Boot starter for the [`nrich-form-configuration`][nrich-form-configuration-url] module. The purpose of [`nrich-form-configuration`][nrich-form-configuration-url] is to provide
a central place for constraint definitions by converting constraints defined on the server-side in a form that can be used on the client-side, thus avoiding constraint repetition on both server and
client side.

Starter module provides a `@Configuration` class ([`NrichFormConfigurationAutoConfiguration`][nrich-form-configuration-auto-configuration-url]) with default configuration of
[`nrich-form-configuration`][nrich-form-configuration-url] module, a `@ConfigurationProperties` class ([`NrichFormConfigurationProperties`][nrich-form-configuration-properties-url]) with default
configuration values and does automatic bean registration with `spring.factories`. The configuration class permits overriding with the help of conditional annotations.

## Usage

Expand All @@ -18,62 +21,78 @@ The artifact is published on [Maven Central Repository](https://search.maven.org
With Maven:

```xml

<dependency>
<groupId>net.croz.nrich</groupId>
<artifactId>nrich-form-configuration-spring-boot-starter</artifactId>
<version>${nrich.version}</version>
</dependency>

```

With Gradle:

```groovy

implementation "net.croz.nrich:nrich-form-configuration-spring-boot-starter:${nrich.version}"

```

Note if using `nrich-bom` dependency versions should be omitted.
Note if using [`nrich-bom`][nrich-bom-url] dependency versions should be omitted.

### Configuration

Configuration is done through a property file, available properties and descriptions are given bellow (all properties are prefixed with nrich.form-configuration which is omitted for readability):
The configuration is done through a property file. Available properties and descriptions are given bellow (all properties are prefixed with **nrich.form-configuration** which is omitted for
readability):

| property | description | default value |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| default-converter-enabled | Whether default converter service `DefaultConstrainedPropertyValidatorConverterService` for converting `ConstrainedProperty` instances to `ConstrainedPropertyClientValidatorConfiguration` is enabled | true |
| form-configuration-mapping | Mapping between a client side form identifier and class holding the constraints for the form (usually the class accepted as input on the server side) | |
| property | description | default value |
|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| default-converter-enabled | whether default converter service [`DefaultConstrainedPropertyValidatorConverterService`][default-constrained-property-validator-converter-service-url] for converting [`ConstrainedProperty`][constrained-property-url] instances to [`ConstrainedPropertyClientValidatorConfiguration`][constrained-property-client-validator-configuration-url] is enabled | true |
| form-configuration-mapping | mapping between a client side form identifier and class holding the constraints for the form (usually the class accepted as input on the server side) | |

The default configuration values in yaml format for easier modification are given bellow:
The default configuration values are given bellow in a yaml format for easier modification:

```yaml

nrich.form-configuration:
default-converter-enabled: true
form-configuration-mapping:

```

The default converter should be enabled unless users want to provide a completely custom implementation. Overriding of specific constraint properties display configuration resolving can be
done by implementing a `ConstrainedPropertyValidatorConverterService` interface. That interface implementation will be picked up by the module and used before default converter if `supports`
method returns true.
The default converter should be enabled unless users want to provide a completely custom implementation. To override the resolving of specific constraint properties display configuration a custom
implementation of [`ConstrainedPropertyValidatorConverterService`][constrained-property-validator-converter-service-url] interface should be provided. That interface implementation will be picked up
by the module and used before the default converter if `supports` method returns true.

### Using the module

Users should specify a form-configuration-mapping property list that will contain mappings between client side form identifier and server side input. An example configuration is given bellow:
Users should specify a `form-configuration-mapping` property map that will contain mappings between the form identifiers on the client-side and the classes that hold constraints on the server-side.

```yaml
An example configuration is given bellow:

```yaml
nrich.form-configuration:
default-converter-enabled: true
form-configuration-mapping:
user.create-form: net.croz.nrich.example.CreateUserRequest
user.update-form: net.croz.nrich.example.UpdateUserRequest

```

This module should be used from the client side and for that a REST endpoint is exposed on `nrich/form/configuration/fetch` URL. The endpoint expects a list of formIdList
(key inside form-configuration-mapping map) for which the `FormConfiguration` list will be returned. `FormConfiguration` contains a list of properties with defined constraints, clients can then
convert that configuration to specific client configurations and apply them to their forms.
This module exposes REST endpoint on `nrich/form/configuration/fetch` URL so that the client can retrieve constraint definitions. The endpoint expects a POST request with a list of form ids
(keys inside `form-configuration-mapping` map) for which a list with [`FormConfiguration`][form-configuration-url] will be returned for each mapped form id.
[`FormConfiguration`][form-configuration-url] contains a list of properties for constraints defined in server-side class which clients can then convert to specific client-side configurations and
apply them to their forms. If user needs to fetch constraint descriptions for all registered forms, module also exposes `nrich/form/configuration/fetch-all` endpoint that returns all configurations.

[//]: # (Reference links for readability)

[nrich-form-configuration-url]: ../nrich-form-configuration/README.md

[nrich-bom-url]: ../nrich-bom/README.md

[nrich-form-configuration-auto-configuration-url]: ../nrich-form-configuration-spring-boot-starter/src/main/java/net/croz/nrich/formconfiguration/starter/configuration/NrichFormConfigurationAutoConfiguration.java

[nrich-form-configuration-properties-url]: ../nrich-form-configuration-spring-boot-starter/src/main/java/net/croz/nrich/formconfiguration/starter/properties/NrichFormConfigurationProperties.java

[default-constrained-property-validator-converter-service-url]: ../nrich-form-configuration/src/main/java/net/croz/nrich/formconfiguration/service/DefaultConstrainedPropertyValidatorConverterService.java

[constrained-property-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/ConstrainedProperty.java

[constrained-property-client-validator-configuration-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/ConstrainedPropertyClientValidatorConfiguration.java

[constrained-property-validator-converter-service-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/service/ConstrainedPropertyValidatorConverterService.java

[form-configuration-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/FormConfiguration.java
121 changes: 101 additions & 20 deletions nrich-form-configuration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

## Overview

`nrich-form-configuration` is a module intended to provide a way of resolving server side defined constraints to client side. It resolves `jakarta-validation-api`
constraints defined on classes in a form that can be interpreted by the client side. On server side user registers form id (a string) with class holding constraints and then resolves defined
constraint list from client side using REST API. Messages for constraints are resolved through Spring's `MessageSource`.
`nrich-form-configuration` is a module intended to provide a central place for constraint definitions.
It resolves `jakarta-validation-api` constraints defined on classes in a form that can be interpreted by the client-side. On the server-side user registers a form id (a string) to a class that
defines constraints and can then retrieve the resolved constraint list via REST API. Messages for constraints are resolved through Spring's `MessageSource`.

## Setting up Spring beans

Expand Down Expand Up @@ -40,14 +40,29 @@ public class ApplicationConfiguration {
public FormConfigurationController formConfigurationController(FormConfigurationService formConfigurationService) {
return new FormConfigurationController(formConfigurationService);
}

}
```

## FieldErrorMessageResolverService

[`FieldErrorMessageResolverService`][field-error-message-resolver-service-url] is responsible for resolving messages for constraints (i.e. 'Value cannot be null' for @NotNull constraint).
Default implementation is [`MessageSourceFieldErrorMessageResolverService`][message-source-field-error-message-resolver-service-url] that resolves messages from `MessageSource`.

For example, for class:

```java
package net.croz.nrich.formconfiguration.stub;

public class FormConfigurationServiceNestedTestRequest {

@NotNull
private String propertyName;

}
```

`FieldErrorMessageResolverService` is responsible for resolving messages for constraints (i.e. 'Value cannot be null' for @NotNull constraint). Default implementation
is `MessageSourceFieldErrorMessageResolverService` that resolves messages from `MessageSource`. For example for constraint holding class of
type `net.croz.nrich.formconfiguration.stub.FormConfigurationServiceNestedTestRequest` and `@NotNull` constraint defined on property named `propertyName` following message codes will be
searched:
the following message codes will be searched:

- `net.croz.nrich.formconfiguration.stub.FormConfigurationServiceNestedTestRequest.propertyName.client.NotNull.invalid`
- `formConfigurationServiceNestedTestRequest.propertyName.client.NotNull.invalid`
Expand All @@ -56,26 +71,48 @@ searched:
- `client.NotNull.invalid`
- `NotNull.invalid`

`ConstrainedPropertyValidatorConverterService` is service responsible for converting constraints in a format client can interpret. Default implementation
is `DefaultConstrainedPropertyValidatorConverterService` but users can register their own by implementing `ConstrainedPropertyValidatorConverterService` interface.
---

## ConstrainedPropertyValidatorConverterService

[`ConstrainedPropertyValidatorConverterService`][constrained-property-validator-converter-service-url] is responsible for converting constraints in a format the client can interpret.
Default implementation is [`DefaultConstrainedPropertyValidatorConverterService`][default-constrained-property-validator-converter-service-url] but users can register their own by implementing
[`ConstrainedPropertyValidatorConverterService`][constrained-property-validator-converter-service-url] interface.

[`ConstrainedPropertyValidatorConverterService`][constrained-property-validator-converter-service-url] returns a list of
[`ConstrainedPropertyClientValidatorConfiguration`][constrained-property-client-validator-configuration-url] for each constraint (a list since some constraints on server may translate to multiple
constraints on the client).

---

## FormConfigurationService

[`FormConfigurationService`][form-configuration-service-url] processes constraints defined on a class for form id list and returns a list of [`FormConfiguration`][form-configuration-url] instances
holding client-side constrained property configuration.

---

## FormConfigurationController

[`FormConfigurationController`][form-configuration-controller-url] is REST API exposed to the client.

`ConstrainedPropertyValidatorConverterService` returns a list of `ConstrainedPropertyClientValidatorConfiguration` for each constraint
(a list since some constraints on server may translate to multiple constraints on the client).
It has two POST methods:

`FormConfigurationService` is service that processes constraints defined on a class for form id list and returns a list of
`FormConfiguration` instances holding client side constrained property configuration.
- `fetch` mapped to `nrich/form/configuration/fetch` that accepts a request whose body has a form id list in property `formIdList` and it returns a list of
[`FormConfiguration`][form-configuration-url] instances
- `fetch-all` mapped to `nrich/form/configuration/fetch-all` that returns a list of [`FormConfiguration`][form-configuration-url] instances for every registered form.

`FormConfigurationController` is REST API exposed to client. It has a single POST method `fetch` mapped to `nrich/form/configuration/fetch` that accepts a request holding form id list in
property `formIdList` and it returns a list of `FormConfiguration` instances.
REST API base path of the URL can be changed by setting a custom `nrich.form-configuration.endpoint-path` property value.

## Usage

On server side users should register form id with class that is used to bind values submitted from that form. On client side REST API endpoint for fetching form configuration should be
called (`nrich/form/configuration/fetch`) and received response should be converted to client side constraints and applied to field defined on the form.
On the server-side users should register form id with class that is used to bind values submitted from that form. On the client-side the REST API endpoint for fetching form configuration should be
called (`nrich/form/configuration/fetch`) and received response should be converted to client-side constraints and applied to fields defined on the form.

For following request:
For the following request:

```java
package example;

@Setter
@Getter
Expand Down Expand Up @@ -108,15 +145,33 @@ public class EmployeeRequest {
private BigDecimal income;

}
```

we have a mapping in `application.yml` that maps client-side form (with a form id equal to `example.form`) to the `EmployeeRequest`:

```yaml
nrich.form-configuration:
default-converter-enabled: true
form-configuration-mapping:
example.form: example.EmployeeRequest
```

For request:

```json
{
"formIdList": [
"example.form"
]
}
```

Response sent from server is in following form:
the response sent from server is in the following form:

```json
[
{
"formId": "demo.EmployeeForm",
"formId": "example.form",
"constrainedPropertyConfigurationList": [
{
"path": "firstName",
Expand Down Expand Up @@ -239,3 +294,29 @@ Response sent from server is in following form:


```

If user needs to fetch constraint descriptions for all registered forms, `nrich/form/configuration/fetch-all` endpoint should be queried.

[//]: # (Reference links for readability)

[nrich-form-configuration-url]: ../nrich-form-configuration/README.md

[nrich-bom-url]: ../nrich-bom/README.md

[constrained-property-validator-converter-service-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/service/ConstrainedPropertyValidatorConverterService.java

[default-constrained-property-validator-converter-service-url]: ../nrich-form-configuration/src/main/java/net/croz/nrich/formconfiguration/service/DefaultConstrainedPropertyValidatorConverterService.java

[constrained-property-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/ConstrainedProperty.java

[constrained-property-client-validator-configuration-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/ConstrainedPropertyClientValidatorConfiguration.java

[form-configuration-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/model/FormConfiguration.java

[form-configuration-service-url]: ../nrich-form-configuration-api/src/main/java/net/croz/nrich/formconfiguration/api/service/FormConfigurationService.java

[form-configuration-controller-url]: ../nrich-form-configuration/src/main/java/net/croz/nrich/formconfiguration/controller/FormConfigurationController.java

[field-error-message-resolver-service-url]: ../nrich-form-configuration/src/main/java/net/croz/nrich/formconfiguration/service/FieldErrorMessageResolverService.java

[message-source-field-error-message-resolver-service-url]: ../nrich-form-configuration/src/main/java/net/croz/nrich/formconfiguration/service/MessageSourceFieldErrorMessageResolverService.java