chore: Add separate request/response views (#31640)
This PR gets finer control into what fields are allowed in request-body-only, vs what's allowed in response-body-only. This leaves the fields to separately controlled regarding what can go into the database and what can't. [Slack thread](https://theappsmith.slack.com/archives/CPQNLFHTN/p1710125307810949).
This commit is contained in:
parent
863214785a
commit
4cdbe89586
|
|
@ -16,9 +16,9 @@ import com.appsmith.external.models.Executable;
|
||||||
import com.appsmith.external.models.PluginType;
|
import com.appsmith.external.models.PluginType;
|
||||||
import com.appsmith.external.models.Policy;
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.external.models.Property;
|
import com.appsmith.external.models.Property;
|
||||||
|
import com.appsmith.external.views.ResponseOnly;
|
||||||
import com.appsmith.external.views.Views;
|
import com.appsmith.external.views.Views;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonView;
|
import com.fasterxml.jackson.annotation.JsonView;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
@ -88,9 +88,8 @@ public class ActionCE_DTO implements Identifiable, Executable {
|
||||||
ActionConfiguration actionConfiguration;
|
ActionConfiguration actionConfiguration;
|
||||||
|
|
||||||
// this attribute carries error messages while processing the actionCollection
|
// this attribute carries error messages while processing the actionCollection
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
@Transient
|
@Transient
|
||||||
@JsonView(Views.Public.class)
|
@JsonView(ResponseOnly.class)
|
||||||
List<ErrorDTO> errorReports;
|
List<ErrorDTO> errorReports;
|
||||||
|
|
||||||
@JsonView(Views.Public.class)
|
@JsonView(Views.Public.class)
|
||||||
|
|
@ -106,23 +105,19 @@ public class ActionCE_DTO implements Identifiable, Executable {
|
||||||
@JsonView(Views.Public.class)
|
@JsonView(Views.Public.class)
|
||||||
List<Property> dynamicBindingPathList;
|
List<Property> dynamicBindingPathList;
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
@JsonView(ResponseOnly.class)
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
Boolean isValid;
|
Boolean isValid;
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
@JsonView(ResponseOnly.class)
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
Set<String> invalids;
|
Set<String> invalids;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
@JsonView(ResponseOnly.class)
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
Set<String> messages = new HashSet<>();
|
Set<String> messages = new HashSet<>();
|
||||||
|
|
||||||
// This is a list of keys that the client whose values the client needs to send during action execution.
|
// This is a list of keys that the client whose values the client needs to send during action execution.
|
||||||
// These are the Mustache keys that the server will replace before invoking the API
|
// These are the Mustache keys that the server will replace before invoking the API
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
@JsonView(ResponseOnly.class)
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
Set<String> jsonPathKeys;
|
Set<String> jsonPathKeys;
|
||||||
|
|
||||||
@JsonView(Views.Internal.class)
|
@JsonView(Views.Internal.class)
|
||||||
|
|
|
||||||
7
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/views/RequestOnly.java
vendored
Normal file
7
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/views/RequestOnly.java
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.appsmith.external.views;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended to annotate fields that can be set by HTTP request payloads, but should NOT be included
|
||||||
|
* in HTTP responses sent back to the client.
|
||||||
|
*/
|
||||||
|
public interface RequestOnly extends Views.Public {}
|
||||||
8
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/views/ResponseOnly.java
vendored
Normal file
8
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/views/ResponseOnly.java
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.appsmith.external.views;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended to mark entity/DTO fields that should be included as part of HTTP responses, but should
|
||||||
|
* be ignored as part of HTTP requests. For example, if a field is marked with this annotation, in
|
||||||
|
* a class used with {@code @RequestBody}, it's value will NOT be deserialized.
|
||||||
|
*/
|
||||||
|
public interface ResponseOnly extends Views.Public {}
|
||||||
|
|
@ -6,23 +6,19 @@ import com.appsmith.server.newactions.base.NewActionService;
|
||||||
import com.appsmith.server.refactors.applications.RefactoringService;
|
import com.appsmith.server.refactors.applications.RefactoringService;
|
||||||
import com.appsmith.server.services.LayoutActionService;
|
import com.appsmith.server.services.LayoutActionService;
|
||||||
import com.appsmith.server.solutions.ActionExecutionSolution;
|
import com.appsmith.server.solutions.ActionExecutionSolution;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(Url.ACTION_URL)
|
@RequestMapping(Url.ACTION_URL)
|
||||||
@Slf4j
|
|
||||||
public class ActionController extends ActionControllerCE {
|
public class ActionController extends ActionControllerCE {
|
||||||
|
|
||||||
public ActionController(
|
public ActionController(
|
||||||
LayoutActionService layoutActionService,
|
LayoutActionService layoutActionService,
|
||||||
NewActionService newActionService,
|
NewActionService newActionService,
|
||||||
RefactoringService refactoringService,
|
RefactoringService refactoringService,
|
||||||
ActionExecutionSolution actionExecutionSolution,
|
ActionExecutionSolution actionExecutionSolution) {
|
||||||
ObservationRegistry observationRegistry) {
|
|
||||||
|
|
||||||
super(layoutActionService, newActionService, refactoringService, actionExecutionSolution, observationRegistry);
|
super(layoutActionService, newActionService, refactoringService, actionExecutionSolution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.appsmith.server.controllers.ce;
|
||||||
|
|
||||||
import com.appsmith.external.models.ActionDTO;
|
import com.appsmith.external.models.ActionDTO;
|
||||||
import com.appsmith.external.models.ActionExecutionResult;
|
import com.appsmith.external.models.ActionExecutionResult;
|
||||||
|
import com.appsmith.external.views.RequestOnly;
|
||||||
import com.appsmith.external.views.Views;
|
import com.appsmith.external.views.Views;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.constants.Url;
|
import com.appsmith.server.constants.Url;
|
||||||
|
|
@ -16,7 +17,6 @@ import com.appsmith.server.refactors.applications.RefactoringService;
|
||||||
import com.appsmith.server.services.LayoutActionService;
|
import com.appsmith.server.services.LayoutActionService;
|
||||||
import com.appsmith.server.solutions.ActionExecutionSolution;
|
import com.appsmith.server.solutions.ActionExecutionSolution;
|
||||||
import com.fasterxml.jackson.annotation.JsonView;
|
import com.fasterxml.jackson.annotation.JsonView;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -48,30 +48,25 @@ public class ActionControllerCE {
|
||||||
private final NewActionService newActionService;
|
private final NewActionService newActionService;
|
||||||
private final RefactoringService refactoringService;
|
private final RefactoringService refactoringService;
|
||||||
private final ActionExecutionSolution actionExecutionSolution;
|
private final ActionExecutionSolution actionExecutionSolution;
|
||||||
private final ObservationRegistry observationRegistry;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ActionControllerCE(
|
public ActionControllerCE(
|
||||||
LayoutActionService layoutActionService,
|
LayoutActionService layoutActionService,
|
||||||
NewActionService newActionService,
|
NewActionService newActionService,
|
||||||
RefactoringService refactoringService,
|
RefactoringService refactoringService,
|
||||||
ActionExecutionSolution actionExecutionSolution,
|
ActionExecutionSolution actionExecutionSolution) {
|
||||||
ObservationRegistry observationRegistry) {
|
|
||||||
this.layoutActionService = layoutActionService;
|
this.layoutActionService = layoutActionService;
|
||||||
this.newActionService = newActionService;
|
this.newActionService = newActionService;
|
||||||
this.refactoringService = refactoringService;
|
this.refactoringService = refactoringService;
|
||||||
this.actionExecutionSolution = actionExecutionSolution;
|
this.actionExecutionSolution = actionExecutionSolution;
|
||||||
this.observationRegistry = observationRegistry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonView(Views.Public.class)
|
@JsonView(Views.Public.class)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@ResponseStatus(HttpStatus.CREATED)
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
public Mono<ResponseDTO<ActionDTO>> createAction(
|
public Mono<ResponseDTO<ActionDTO>> createAction(
|
||||||
@Valid @RequestBody ActionDTO resource,
|
@Valid @RequestBody @JsonView(RequestOnly.class) ActionDTO resource,
|
||||||
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName,
|
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) {
|
||||||
@RequestHeader(name = "Origin", required = false) String originHeader,
|
|
||||||
ServerWebExchange exchange) {
|
|
||||||
log.debug("Going to create resource {}", resource.getClass().getName());
|
log.debug("Going to create resource {}", resource.getClass().getName());
|
||||||
return layoutActionService
|
return layoutActionService
|
||||||
.createSingleActionWithBranch(resource, branchName)
|
.createSingleActionWithBranch(resource, branchName)
|
||||||
|
|
@ -82,7 +77,7 @@ public class ActionControllerCE {
|
||||||
@PutMapping("/{defaultActionId}")
|
@PutMapping("/{defaultActionId}")
|
||||||
public Mono<ResponseDTO<ActionDTO>> updateAction(
|
public Mono<ResponseDTO<ActionDTO>> updateAction(
|
||||||
@PathVariable String defaultActionId,
|
@PathVariable String defaultActionId,
|
||||||
@Valid @RequestBody ActionDTO resource,
|
@Valid @RequestBody @JsonView(RequestOnly.class) ActionDTO resource,
|
||||||
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) {
|
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) {
|
||||||
log.debug("Going to update resource with defaultActionId: {}, branch: {}", defaultActionId, branchName);
|
log.debug("Going to update resource with defaultActionId: {}, branch: {}", defaultActionId, branchName);
|
||||||
return layoutActionService
|
return layoutActionService
|
||||||
|
|
@ -178,9 +173,6 @@ public class ActionControllerCE {
|
||||||
* <p>
|
* <p>
|
||||||
* The controller function is primarily used with param applicationId by the client to fetch the actions in edit
|
* The controller function is primarily used with param applicationId by the client to fetch the actions in edit
|
||||||
* mode.
|
* mode.
|
||||||
*
|
|
||||||
* @param params
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
@JsonView(Views.Public.class)
|
@JsonView(Views.Public.class)
|
||||||
@GetMapping("")
|
@GetMapping("")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user