I have a file that contains URLs that must be exposed on a REST API. All URLs represent distinct resources and they must be documented separately. The file contains hundreds of URLs like:
/p1
/p1/p2
/p1/p2/p3
/t1
/t1/t2
/t1/t2/t3
I want to automatically / programmatically generate REST endpoints so that I will be able to call:
GET on https://host/p1/
GET on https://host/p1/p2
GET on https://host/p1/p3
... and so on ...
The logic behind handling the requests is similar for every path, so /p1, /p1/p2, /t1, and so on can be handled by a single function that receives the entire path. In order to handle the request I have a function like this:
function handleRequest(url) {
// this function should be called for every GET request on any of those endpoints
// perform the business logic here
}
Data is stored in a tree data structure, so it makes sense to get a path in the tree and return the data underneath the node the path points to. However, all of these paths are separate resources.
I am writing the code in Java, but the language is not important for now. I would generate a REST endpoint in Spring like this:
@RequestMapping(
path = "/t1",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE,
headers = "Accept=application/json"
)
public ResponseEntity getT1() {
// handle request here
}
However, since the number of resources that must be exposed through the API is very high, it is extremely hard to write a function like the one above for hundreds or thousands of times when the logic that handles the request is the same.
One solution that I found is to use PathPatterns. This would entail having a RequestMapping with a url like "/commonPath/**". The downside of this solution is that I cannot automatically generate documentation via Swagger for the API since there is a single entry point.
How can I automatically generate all these endpoints?
Edit
Documentation basically boils down to having an automatic way of telling what are the available endpoints the user can call. I do not want to write/maintain this manually since the number of URLs is very high. With Swagger, it is very simple. Just annotate the endpoints and a user interface is automatically generated for the clients of the API.
I wish to know more details about your scenario but here are the possible options based on the given information at this point in time.
Solution 1: If your input file is static and you need to expose the APIs based on the static input file then this solution may work well. Just write a program to generate the controller class based on the file.
@RestController
public class MyMultiPathApiController {
@AutoWired
private RestApiHandlerService restApiHandlerService
@RequestMapping(
value = { "/p1", "/p1/p2", "/p1/p2/p3" },
method = GET)
public ResponseEntity<?> myMultiRestApi() {
return restApiHandlerService.handleApiLogic();
}
}
Alternatively request mapping accepts regular expressions as well. Based on the examples you have given you can come up with a regular expression as well.
Solution 2 (Recommended Solution):
If your file is expected to change and you want to expose API dynamically then you need to tweak the spring framework's RequestMappingHandlerMapping
class. Extend the class RequestMappingHandlerMapping
and write the logic which you want to write. You can read the file on the application start and cache it. You can refer to some examples on writing a custom RequestMappingHandlerMapping class here.
I trust this information is helpful. Please let me know if you have any follow up questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With