Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Spring boot dynamically create end points based on the content of the property file?

Tags:

java

rest

spring

So far I am creating end points like this:

@RequestMapping(value = "/test", method = RequestMethod.POST)
public @ResponseBody String indexPost(HttpServletRequest request, HttpServletResponse response)
    throws Exception {
//Doing calculations
return "Result";
}

But I would like to reach the application.properties when the server starts, to read out the data stored like this:

methods: {
"endpointOne": "DBStoredProcedure1",
"endpointTwo": "DBStoredProcedure2"
}

So when my Spring Boot application starts, it would create all the POST endpoints based on the property file with the names of the first parameters (like "endpointOne"), and would call (and return the result of) the stored procedure which is defined as the second parameter (like "DBStoredProcedure1").

Is it possible to do?

like image 242
Macskasztorik Avatar asked Dec 28 '16 10:12

Macskasztorik


2 Answers

Yes you can. A little bit differently though than you try to do it at the moment.

The best is to use a "PathVariable" - you find detailed information here:

https://spring.io/guides/tutorials/bookmarks/

http://javabeat.net/spring-mvc-requestparam-pathvariable/

Your method at the Controller class would look something like this:

 @RequestMapping(value="/{endPoint}", method=RequestMethod.POST)
public String endPoint(@PathVariable String endPoint) {
   //Your endPoint is now the one what the user would like to reach
   //So you check if your property file contains this String - better to cache it's content
   //If it does, you call the service with the regarding Stored Procedure.
   String sPName = prop.getSPName(endPoint); //You need to implement it.
   String answer = yourService.execute(sPName);
   return answer; 
 }

Obviously you need to implement a method to handle those queries which are not found in the property file, but you get the idea.

like image 146
Mr.Fireman Avatar answered Oct 13 '22 03:10

Mr.Fireman


You can use a wild card "/*" as the value in controller. So that all your endpoints would hit the same controller request method.

Below is the code sample.

@RequestMapping(value = "/*", method = RequestMethod.GET, headers="Accept=*/*", produces = { "application/json" })
    public ResponseEntity<Object> getData(@RequestParam Map<String, String> reqParam, HttpServletRequest request)
            throws WriteException, IOException{

        MessageLogger.infoLog(EquityControllerImpl.class, GETQADTRSTOCKPRICELOGS,
                ENTRY);

        // Get Request URI
        MessageLogger.infoLog("Request URI: " + request.getRequestURI());
        String requestUri = request.getRequestURI();


        //Read all request parameters
        Map<String, String> requestParamMap = new HashMap<>();
        for (Map.Entry<String, String> param: reqParam.entrySet()
             ) {
            System.out.println("Parameter: " + param.getKey() + " ----> Value: " + param.getValue());
            requestParamMap.put(param.getKey(),param.getValue());
        }
}

Also you can define static swagger.json and use this in the swagger configuration.

    @Configuration
@EnableSwagger2
@Import(SpringDataRestConfiguration.class)
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.finance.dataplatform.*"))
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build().apiInfo(getApiInfo());
    }

    private ApiInfo getApiInfo() {
        return new ApiInfoBuilder().title("Investment Management").build();
    }

    private static Predicate<String> matchPathRegex(final String... pathRegexs) {
        return new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                for (String pathRegex : pathRegexs) {
                    if (input.matches(pathRegex)) {
                        return true;
                    }
                }
                return false;
            }
        };
    }

    @Bean
    WebMvcConfigurer configurer () {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addResourceHandlers (ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/config/swagger.json")
                        .addResourceLocations("classpath:/config");
            }
        };
    }


    @Primary
    @Bean
    public SwaggerResourcesProvider swaggerResourcesProvider(InMemorySwaggerResourcesProvider defaultResourcesProvider) {
        return () -> {
            SwaggerResource wsResource = new SwaggerResource();
            wsResource.setName("default");
            wsResource.setSwaggerVersion("2.0");
            wsResource.setLocation("/config/swagger.json");

            //List<SwaggerResource> resources = new ArrayList<>(defaultResourcesProvider.get());
            List<SwaggerResource> resources = new ArrayList<>();
            resources.add(wsResource);
            return resources;
        };
    }
}
like image 24
Santhoshm Avatar answered Oct 13 '22 01:10

Santhoshm