[ https://issues.apache.org/jira/browse/SOLR-15737?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17617923#comment-17617923 ]
Jason Gerlowski edited comment on SOLR-15737 at 10/14/22 7:07 PM: ------------------------------------------------------------------ Better late than never, here's an updated step-by-step using the new, preferred API framework. h3. Creating a V2 API [New Framework] # *Create a class to hold your v2 API* API class names generally end with "API". API classes should extend {{JerseyResource}} (or some subclass descended from that root). ** JAX-RS can inject some common objects into API classes via a constructor. {{{}CoreContainer{}}}, {{{}SolrQueryRequest{}}}, and {{SolrQueryResponse}} instances are commonly injected this way. If your API's logic requires any of these, create a constructor to receive them and annotate it with the {{@Inject}} annotation, as seen in the example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L65]. (The objects required to execute the API might not be apparent up front, but this can always be changed later.) # {*}Define a POJO ("Plain Old Java Object") class to represent the API requests body{*}. Only necessary for POSTs and PUTs. Typically this class can live inside your newly-created "API" class, and be marked as "public static". It should implement the empty {{JacksonReflectMapWriter}} interface. Instance variables should be public, and annotated with the Jackson {{@JsonProperty}} annotation, as in the example [here|https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L154]. # {*}Define a POJO class to represent the API response{*}. Re-use of an existing class is often possible here. The conventions mentioned above for the request-body class also apply here. If the response structure is too complex or hard to discern, this step can be skipped (see the second sub-bullet below for more details). # {*}Create a method in your API class to represent the API{*}. (See example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L75].) ** The method should take an argument representing each path and query parameter (annotated with the {{@QueryParam}} or {{@PathParam}} JAX-RS annotations respectively). If the API is a PUT or POST that takes in a request-body, the method can take the request-body POJO defined earlier as its final argument (no annotation needed for this method arg). ** As a return value, the created method should return the response-body POJO created earlier. If you opted not to create a response-body POJO earlier for complexity reasons, the created method should return a generic type, like the commonly-used {{{}NamedList<Object>{}}}. # *Add JAX-RS annotations to your API class and method* These are used to indicate the HTTP path, verb, and "permission" for your API. ** {{@Path}} annotations should usually be added at the class level, though they can also be included at the method level (effectively concatenating the values of the class and method annotations). {{@Path}} supports a limited regex syntax, and curly-brackets can be used to create named placeholders for path-parameters, as shown [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L61]. ** The HTTP verb can be specified as an annotation at the method level using one of JAX-RS' verb annotations (e.g. {{{}@GET{}}}, {{{}@POST{}}}, {{{}@DELETE{}}}, etc). ** The associated permission (a value from Solr's [PermissionNameProvider.Name enum|https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java#L37] should be specified at the method level using the {{@PermissionName}} annotation, as seen [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L74]. # {*}Move API logic from v1 request-handler to the new API class/method{*}. ** For the most part this is "normal" Java development. Find the relevant section of the associated RequestHandler and move it into the new v2 class or refactor it into a sharable utility class that the v2 API class can use. ** In its place, the RequestHandler should be updated to instantiate the v2 API class and call the API method that you created in the steps above. The method retval can then be folded back into a SolrQueryResponse object, which most v1 codepaths use to represent the API response. A good example of this can be found [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java#L323] # *Modify the relevant RequestHandler to register the new v2 API* JAX-RS APIs are registered using the poorly-named {{getJerseyResources}} method, as in the example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java#L2073]. Hope that makes some sense at least? If anyone attempts this and finds issues, let me know and I'll try to correct it. It might make sense as an addition to Solr's collection of "dev-docs" here, but we'll see whether or not it's helpful first I guess. was (Author: gerlowskija): Better late than never, here's an updated step-by-step using the new, preferred API framework. h3. Creating a V2 API [New Framework] # *Create a class to hold your v2 API* API class names generally end with "API". API classes should extend {{JerseyResource}} (or some subclass descended from that root). ** JAX-RS can inject some common objects into API classes via a constructor. {{{}CoreContainer{}}}, {{{}SolrQueryRequest{}}}, and {{SolrQueryResponse}} instances are commonly injected this way. If your API's logic requires any of these, create a constructor to receive them and annotate it with the {{@Inject}} annotation, as seen in the example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L65]. (The objects required to execute the API might not be apparent up front, but this can always be changed later.) # {*}Define a POJO ("Plain Old Java Object") class to represent the API requests body{*}. Only necessary for POSTs and PUTs. Typically this class can live inside your newly-created "API" class, and be marked as "public static". It should implement the empty {{JacksonReflectMapWriter}} interface. Instance variables should be public, and annotated with the Jackson {{@JsonProperty}} annotation, as in the example [here|https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L154]. # {*}Define a POJO class to represent the API response{*}. Re-use of an existing class is often possible here. The conventions mentioned above for the request-body class also apply here. If the response structure is too complex or hard to discern, this step can be skipped (see the second sub-bullet below for more details). # {*}Create a method in your API class to represent the API{*}. (See example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L75].) ** The method should take an argument representing each path and query parameter (annotated with the {{@QueryParam}} or {{@PathParam}} JAX-RS annotations respectively). If the API is a PUT or POST that takes in a request-body, the method can take the request-body POJO defined earlier as its final argument (no annotation needed for this method arg). ** As a return value, the created method should return the response-body POJO created earlier. If you opted not to create a response-body POJO earlier for complexity reasons, the created method should return a generic type, like the commonly-used {{{}NamedList<Object>{}}}. # *Add JAX-RS annotations to your API class and method* These are used to indicate the HTTP path, verb, and "permission" for your API. ** {{@Path}} annotations should usually be added at the class level, though they can also be included at the method level (effectively concatenating the values of the class and method annotations). {{@Path}} supports a limited regex syntax, and curly-brackets can be used to create named placeholders for path-parameters, as shown [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L61]. ** The HTTP verb can be specified as an annotation at the method level using one of JAX-RS' verb annotations (e.g. {{{}@GET{}}}, {{{}@POST{}}}, {{{}@DELETE{}}}, etc). ** The associated permission (a value from Solr's [PermissionNameProvider.Name enum|https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java#L37] should be specified at the method level using the {{@PermissionName}} annotation, as seen [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java#L74]. # {*}Move API logic from v1 request-handler to the new API class/method{*}. ** For the most part this is "normal" Java development. Find the relevant section of the associated RequestHandler and move it into the new v2 class or refactor it into a sharable utility class that the v2 API class can use. ** In its place, the RequestHandler should be updated to instantiate the v2 API class and call the API method that you created in the steps above. The method retval can then be folded back into a SolrQueryResponse object, which most v1 codepaths use to represent the API response. A good example of this can be found [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java#L323] # *Modify the relevant RequestHandler to register the new v2 API* JAX-RS APIs are registered using the poorly-named {{getJerseyResources}} method, as in the example [here|https://github.com/apache/solr/blob/a1ee7c1d0de32779109cb8b66a4319a0f8c85037/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java#L2073]. Hope that makes some sense at least? If anyone attempts this and finds issues, let me know and I'll try to correct it. It might make sense as an addition to Solr's collection of "dev-docs" here, but we'll see over time I guess. > Ensure all (desired) v1 APIs have v2 equivalent > ----------------------------------------------- > > Key: SOLR-15737 > URL: https://issues.apache.org/jira/browse/SOLR-15737 > Project: Solr > Issue Type: Improvement > Components: v2 API > Reporter: Jason Gerlowski > Priority: Major > Labels: V2, newdev > > Nothing in Solr's build system enforced consistency across v1<->v2, so as a > result today, many v1 APIs (or API sub-commands) have no v2 counterpart. In > some rare cases this was intentional (e.g. > \{{/solr/admin/collections?action=MIGRATESTATEFORMAT}} ), but in most cases > it's the result of unintentional omission. > This ticket aims to remedying this, by finding v1 APIs without a v2 > counterpart and adding them where desired. -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org For additional commands, e-mail: issues-h...@solr.apache.org