-1

I'm creating some Spring app with REST Controller for communication with frontend I have some complex objects containing reference to other objects. I want to make a Mockup class for those objects to send those mockups instead of real objects. Object -> Mockup conversion is easy, but I can't seem to find good solution for conversion of JSON objects into proper objects (I'm not receiving full data for the nested object, just some Id that let's me extract it from DB). I think I need to @Autowire object I receive from REST POST, but I neither know if it's possible nor if it's good practice. What's the proper solution for extracting nested dependancies for objects created from deserialized JSON?

Relevant code snippets:

public class Object {
    NestedObject nestedObject;
    ...
}

//That's the part I'm not sure is proper solution
public class ObjectMockup {
    @Autowired
    private NestedObjectService nestedObjectService;
    ...
}

@PostMapping("/new-object")
public ObjectMockup postNewObject(@RequestBody ObjectMockup objectMockup) {
    Object object = objectMockup.mockToObject();
    ...
    return new ObjectMockup(object);
}

When I do it like that, NestedObjectService is not initialized and throws Exception as soon as I try to extract nested object from database, Probably because REST Controller did not Autowire Mockup's attribute.

matszwecja
  • 6,357
  • 2
  • 10
  • 17
  • If you just get data over the rest interface , you should use GET method. You can use POST of course, but that's not the standard way.U Should use proper http method. In the method where you receive the data from frontend, just use the minimal model to deserialize data. Go to the db, load the data into model, that fit to the database. If it contains other data or sensitive data, you should create a separate object to the response and copy all the necceserry fields into that, then return with the new object. It is tireing to create the mapping on your own, so use a mapper lib like MapStruct. – zlaval May 14 '20 at 22:17
  • Problem is not with Rest methods, this is post because it updates data on the DB with one coming from HTTP request. The thing is I cannot just load the data from the DB when using Spring, I need to do it through Services and they need to be Autowired. Rest does not seem to be doing Autowiring on the objects from HTTP request. – matszwecja May 14 '20 at 22:24
  • Your mockup object is not a managed object. You should inject your service into the controller. Never mix model (data) objects with business logic. – zlaval May 14 '20 at 22:29
  • To find good answers online, it helps to use the coming used descriptions. What you explain is that your DTOs contain only IDs for nested objects. Your DTOs are sent as Json. And you want to map your DTOs to business objects by expanding the nested objects with full data from the DB. – tkruse May 15 '20 at 00:08
  • Another similar question, using Jackson directly instead of mapstruct: https://stackoverflow.com/questions/46650940/deserializing-from-json-using-foreign-key – tkruse May 15 '20 at 00:18
  • Do you need the "Object" class nested objects to be lazy loaded, or can they be loaded eagerly? – tkruse May 15 '20 at 00:37

1 Answers1

0

Instead of having a method objectMockup.mockToObject() that fetches the data from the DB, you could:

  1. Inject the service to the method

    objectMockup.mockToObject(nestedObjectService)

  2. Have a static factory method that takes the service and the mock:

    NestedObject.mockToObject(objectMockup, nestedObjectService)

  3. Have a separate MappingService:

    @Service
    public class MockToObjectMapperService {
        @Autowired NestedObjectService nestedObjectService;
    
        public Object mockToObject(objectMockup) {...}
    }
    
    // in Controller
    Object object = mockToObjectMapperService.mockToObject(objectMockup);
    

Though your NestedObjectService could also contain this mapping method.

tkruse
  • 10,222
  • 7
  • 53
  • 80