How to implement the simplest alien in a REST webservice?

后端 未结 2 792
梦谈多话
梦谈多话 2020-12-18 03:00

I need a JSON endpoint that return data directally from a stored procedure. Example:

@Procedure(\"complex\"         


        
2条回答
  •  一个人的身影
    2020-12-18 03:43

    I am trying to respond... It is only "the simplest" for my view point and my basic tests, you can show another solution to get the bounty.

    Starting as " https://stackoverflow.com/q/41880120/287948 " context.... And, as I am using PostgreSQL (where a SELECT f(x) is valid), the @Query (with nativeQuery = true ) is a workaround for @Procedure...

    PROBLEMS WITH THIS ANSWER: not used @Procedure... After Patrick's answer I see (and edited this line) that you can replace @Query to @Procedure (and other things as specified by Patrick) that the method is the same!


    3 steps for add "alien @Query" in an existent domain

    Any Spring domain can use any @Query, so the domain choice is only a kind of "house organization" and semantic, no constraint over your native SQL code and domain/repository choice.

    1. At domain's domain.repository package file, add a method with @Query and with other imports add all Query-context imports (QueryAnnotation, JpaRepository, query.Param, etc. if need);

    2. At domain's service package file, add the new custom "find" method definition.

    3. At controll's method, call the method defined in the service.


    Illustrating with real files

    Step1: add the new @Query into a existing repository file, eg. myprj/address/domain/repository/ICityRepository.java

    package com.myprj.address.domain.repository;  // old
    
    import com.myprj.address.domain.entity.City;   //old
    // ... other project's specific (old)
    import org.springframework.data.jpa.repository.JpaRepository; 
    import org.springframework.data.jpa.repository.Query; // new
    import org.springframework.data.repository.query.Param; // new
    import org.springframework.data.jpa.repository.query.Procedure; // new
    
    @Repository
    public interface ICityRepository extends BaseRepository { //old
        Page findByState(State state, Pageable pageable); //old
    
        // here an alien example! (simplest is a call to a constant value)
        @Query(nativeQuery = true, value= "SELECT 1234.5678") // NEW! 
        Double findCustom();
    
    }
    

    The alien is there!

    Step2: import repository and add defined findCustom() into a existing service file, eg. myprj/address/service/CityService.java

    package com.myprj.address.service; // old
    
    import com.myprj.address.domain.entity.City;
    // ... other project's specific (old)
    
    @Service   
    public class CityService 
           extends BaseService {   // old
    
        @Autowired
        public CityService(ICityRepository repository) {super(repository);} // old
    
        public Page findByState(State state, Pageable pageable) {
            return repository.findByState(state, pageable);
        } // old
    
        public Double findCustom() { return repository.findCustom(); }  // NEW!!
    
    }
    

    Step3: add defined cityService.findCustom() into a existing controller file, eg. myprj/address/controller/CityController.java ... It is a dummy endpoint to test and show the query result,

    package com.myprj.address.controller;  // old
    
    import com.myprj.address.service.CityService;  // reuse old
    // ... other project's specific (old)
    
    @RestController   // old
    @RequestMapping(value = "/zip", produces = "application/json")  // old
    public class ZipController {   // old
    
        @Autowired  // old
        private CityService cityService;  // old, so reuse it
    
        // .. many many endpoints ... OLD    
    
        // NEW!!
        @RequestMapping(value="/dummy", method=RequestMethod.GET)
        @ResponseStatus(HttpStatus.OK)
        public String dummy() {
            double x = cityService.findCustom();
            return "{\"success\":"+x+"}";
        }
    }
    

    Reducing to 2 steps and 2 files

    As showed by Patrick you can add @Autowired to the repository to set it, and use repository.findCustom() directly in the Controller.java file.

提交回复
热议问题