RPC in Internet transport layer, use dto is reasonable. Http controller? If all controller are used by front end, parameter defined as VO?
I guess you are asking whether the argument of the rest controller method can be a DTO.
Well it will depend on the framework you use. The http parameters are strings.
If the framework has an utility mechanism (probably an annotation) that lets you map the http params you receive into a DTO you supply as the rest controller method arg, there's no problem in the arg being a DTO.
If the framework doesn't have such utility (it just maps each http param into an string arg of the rest controller method), then you have to build manually the DTO in the rest controller method.
I don't know if Spring has such an utility annotation similar to #PathVariable but for gathering multiple request params into a DTO object.
UPDATE:
Spring #RequestBody annotation deserializes the JSON into the java object argument of the rest controller method. So, the arg annotated with #RequestBody is a DTO.
DDD says nothing about which type must be the params of a rest api. They can be either a DTO or Strings, it doesn't matter. If they where strings, you would have to construct the DTO by yourself. Using #RequestBody, Spring framework does it for you.
In java, an object that is carries between process is named following the camel case notation and having the DTO suffix.
e.g. ServiceMessageDTO
DTO stands for data transfer object.
This applies also to the request body parameters from the rest webmethods.
Related
I have a Spring RestController with an endpoint consuming JSON. It converts the JSON to an object, and validates the fields (using bean validation):
#RequestMapping(method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<?> myMethod(#Valid #RequestBody MyEntity e) {
...
}
I'd like to intercept the invocation of this method only after the conversion and validation has taken place to have access to MyEntity and possibly abort execution.
Using Spring interceptors, I can only intercept the request before it reaches the method - so I don't have access to the validated bean. I can use Spring AOP and add a pointcut, but is there a way of aborting the execution nicely – ideally without throwing an exception?
This functionality is outside of the business logic of this method, and is temporary – so I want to separate it.
A possible solution is to create a bean proxy between the Spring's proxy object and an object of your original class. To do that you need:
Implement your own BeanPostProcessor.
Spring will call its postProcessBeforeInitialization() method right after it has instantiated an object of your class, but before wrapping and initialising it. In this method, identify which beans must be provided with your functionality. It's often done by means of your custom annotations on methods or classes.
Create your own proxy for the beans from step 2. You can use cglib or something more modern for that. Your proxy will make all the checks you need and then call the parent's method if everything is ok, or just silently return from the method if something is wrong.
Return your proxy from postProcessBeforeInitialization(), it will instruct Spring to use it instead of the original bean.
As the result, Spring will create proxy of your proxy, not of the original object. When a request arrives, Spring will do the validation and send it to your proxy. Your proxy will make all your custom checks and decide on whether to send it further to your original class or to return immediately.
I'm using Vertx 3, and I'm trying to find a good decoupled module that knows to turn query-string, headers and both content-type and body into a bean?
I know spring does that and various other frameworks as well, but I don't want to introduce a new framework i just want a super fast model binder that will either know to auto bind to a certain method or at least auto bind a certain class so i can invoke my rest method that currently accept one parameter, which is the model.
public ResponseBase query(QueryRequest model){ ... }
I don't mind adding annotations to the parameters etc.
Thanks!
Current my team use vertx Json.decodeValue to turn body (json string) to java class.
MyClass body = Json.decodeValue(rc.getBodyAsString(), MyClass.class);
to config Json to handle unknown properties, I setting
Json.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
for your query string, I think it is easy to write a class to convert it to a json string :)
I also catch DecodeException on Json.decodeValue to re throw a 400 Bad Request error.
Thanks to #RestController I don't need to add annotation #ResposneBody, cause spring knows that it is rest controller, and he will not generate view, but instead it will return json object.
Unfortunately there is one more annotation related to this topic. It is #RequestBody, when controller method accept json object as a parameter. And it will have to be pointed before that parameter.
My question is there a way to get rid of that annotation (#RequestBody).? If my controller is rest controller (#RestController instead of regular #Controller) it should be demanded from spring?
No, you'll have to specify #RequestBody. A Java method can have only a single return value, and so the #ResponseBody is unambiguous, but there are multiple possible ways that mapped controller parameters might be interpreted (in particular, using #ModelAttribute with form encoding is a very common alternative to #RequestBody with JSON), and you'll need to tell Spring how to map the incoming request.
In RESTful web services written using Jersey, I know I can access path parameters and query string parameters using #PathParam and #QueryParam annotaions. But in a web service written by someone else I saw a method like below.
#POST
#Path("/sms/receive")
#Consumes("application/json")
#Produces("application/json")
public Response smsReceive(String jsonBody) {
//Code here...
}
There is no #PathParam or #QueryParamannotation before the argument jsonBody.
Can anybody explaing what this argument means and how to set value for it when calling this service.
Can I use multiple parameters without annotations?
Thanks.
The service above does not handle query or path parameters at all.
It #Consumes JSON input. That's what the method's parameter jsonBody is referring to.
If someone would want to instruct this service he would add a json payload to the http request which the service (in this case) receives as a simple String. The String then needs to be parsed.
Of course you can combine Path/Query Parameters with JSON Payloads.
I am currently working on a project which was maintained by some other team and now i need to maintain it. While i was going through the project i found some thing below:
In jax-rs controller it was annotated by #Consumes(MediaType.APPLICATION_JSON) but the method takes request body as String rather than JSON. Then what is the use of the annotation? Does it help in content negotiation anyway?
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response createCake(final String requestBody){.......}
How it is converting a JSON body to string?
My technology stack if it anyway helps to answer:
JAX-RS
Spring 3.2
Jersey 2.4
The #Consumes serves the following purpose. It restricts the mapping for your handlers. For example, you may have two handlers for the path /resource, one mapped to consume XML and the other mapped to consume json. The dispatcher will choose the right one based on the request's content-type.
The parameter type can be anything as long as there is an appropriate converter for the specified media type to the parameter type itself. In this case, there's very likely a converter from any media type to String.