[ 
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

Reply via email to