https://d226lax1qjow5r.cloudfront.net/blog/blogposts/java-client-version-4-dr/java-version-4.png

Ya está aquí la versión 4 de la biblioteca de clientes Java de Nexmo

Publicado el May 4, 2021

Tiempo de lectura: 5 minutos

Hoy hemos lanzado la versión 4.0.0 de nuestra Biblioteca Cliente Nexmo Java. Aunque nos sentimos muy bien con nuestras versiones 3.x de la biblioteca, nos dimos cuenta de que hay algunas cosas que la detienen de proporcionar la experiencia de usuario ideal.

Una nueva versión principal implica un par de interrupciones de la compatibilidad con versiones anteriores, pero toda una serie de nuevas y brillantes funciones. Quería ofrecer algunos consejos de migración y explicar por qué hemos elegido esta dirección.

Para consultar la lista completa de cambios, puede consultar nuestro registro de cambios en la página de la versión

Compatibilidad con Java 7

Fue una decisión difícil, pero decidimos que era hora de dejar de dar soporte oficial a Java 7. Decidir la siguiente versión de Java a la que dirigirnos también fue un reto, pero hemos actualizado la versión de destino a Java 8.

Fin del soporte de Oracle

Oracle puso fin a las actualizaciones públicas de Java 7 en abril de 2015. Aunque sigue ofreciendo soporte ampliado hasta julio de 2020, lleva tiempo animando a los usuarios a actualizar.

Wikipedia Java Version TableWiki Java Version

Es cierto que otros JDK siguen actualizados para Java 7, pero creemos que es uno de los factores limitantes para poder avanzar en el desarrollo.

Recientemente Fin de la compatibilidad con protocolos TLS heredados. Adicionalmente, Maven Central dejó de dar soporte en mayo de 2018. Esto complica el proceso de integración continua y hace que mantener la biblioteca con soporte para Java 7 sea un desafío adicional.

Las versiones de Java avanzan

No tomamos esta decisión a la ligera y, con las nuevas versiones pasando a una cadencia de lanzamiento de cadencia de 6 mesesno creemos que las futuras versiones sean tan drásticas. Donald Smith, de Oracle, afirma:

Pasar de Java 9->10->11 es más parecido a pasar de 8->8u20->8u40 que de 7->8->9. Al principio da miedo verlo cuando estás acostumbrado a grandes lanzamientos cada tres años y tienes un modelo mental del enorme impacto de esos grandes cambios. La cadencia semestral no es eso.

Queremos ser lo más inclusivos posible, y hemos añadido algunas funciones al cliente para ayudar a determinar la mejor versión de Java a la que dirigirse en el futuro.

Instanciación del cliente

Instanciar el objeto NexmoClient objeto ya no requiere pensar en cómo autenticarse. En su lugar, ahora se le proporciona un Builder para ayudarle a construir el cliente utilizando varias opciones de configuración.

Antiguo

Así es como se instanciaba el NexmoClient se instanciaba para su uso tanto con la SMS API como con la Voice API:

AuthMethod tokenAuth = new TokenAuthMethod(NEXMO_API_KEY, NEXMO_API_SECRET);
AuthMethod applicationAuth = new JWTAuthMethod(NEXMO_APPLICATION_ID,
        FileSystems.getDefault().getPath(NEXMO_APPLICATION_PRIVATE_KEY_PATH)
);

NexmoClient client = new NexmoClient(tokenAuth, applicationAuth);

Este proceso requiere que comprenda cómo funciona funciona el esquema de autenticación. También nos pareció que utilizar nombres como TokenAuthMethod y JWTAuthMethod no eran suficientemente intuitivos.

Nuevo

Con la nueva versión, así es como se puede instanciar NexmoClient para utilizarlo tanto con la API de SMS como con la de Voice:

NexmoClient client = new NexmoClient.Builder()
        .apiKey(NEXMO_API_KEY)
        .apiSecret(NEXMO_API_SECRET)
        .applicationId(NEXMO_APPLICATION_ID)
        .privateKeyPath(NEXMO_PRIVATE_KEY_PATH)
        .build();

También puede proporcionarle el contenido de su archivo de clave privada, en caso de que lo cargue desde otra fuente:

NexmoClient client = new NexmoClient.Builder()
        .apiKey(NEXMO_API_KEY)
        .apiSecret(NEXMO_API_SECRET)
        .applicationId(NEXMO_APPLICATION_ID)
        .privateKeyContents(NEXMO_PRIVATE_KEY_CONTENTS)
        .build();

Como usuario, sólo deberías tener que preocuparte de las credenciales que tienes. No deberías tener que preocuparte por cuál AuthMethod usar con tu clave y secreto de la API, simplemente proporciona al Builder con todas las credenciales que tengas.

Hay algunas advertencias al proporcionar las cosas de esta manera. Si proporciona una clave API, también debe proporcionar un secreto o un secreto de firma. Si no lo hace, el método build lance un error NexmoClientCreationException.

El objeto de control de llamadas Nexmo

El sitio Objeto de Control de Llamada Nexmo (NCCO) han recibido una importante revisión en esta actualización. Originalmente, llamábamos a nuestros serializadores clases NCCO con nombres como TalkNcco, InputNcco, ConnectNcco. Sin embargo, esto no coincide con la convención de nomenclatura real.

Nuestra Guía NCCO dice

Un Objeto de Control de Llamada Nexmo (NCCO) es una matriz JSON de acciones que se utiliza para controlar el flujo de una llamada Voice API.

Así que las renombramos a clases de acción con nombres como TalkAction, InputActiony ConnectAction. Además, proporcionamos una envoltura de colección especial llamada Ncco para unirlas todas y manejar la construcción de la estructura JSON.

Antiguo

A continuación se explica cómo crear una OCNC para que un usuario grabe un mensaje:

Route answerRoute = (req, res) -> {
    String recordingUrl = String.format("%s://%s/webhooks/recordings", req.scheme(), req.host());

    TalkNcco intro = new TalkNcco("Please leave a message after the tone, then press #.");

    RecordNcco record = new RecordNcco();
    record.setEventUrl(recordingUrl);
    record.setEndOnSilence(3);
    record.setEndOnKey('#');
    record.setBeepStart(true);

    TalkNcco outro = new TalkNcco("Thank you for your message. Goodbye");

    Ncco[] nccos = new Ncco[]{intro, record, outro};

    res.type("application/json");

    return new ObjectMapper().writer().writeValueAsString(nccos);
};

Nuevo

Ahora, puedes hacer algo como esto:

Route answerRoute = (req, res) -> {
    String recordingUrl = String.format("%s://%s/webhooks/recordings", req.scheme(), req.host());

    TalkAction intro = new TalkAction.Builder("Please leave a message after the tone, then press #.").build();

    RecordAction record = new RecordAction.Builder()
            .eventUrl(recordingUrl)
            .endOnSilence(3)
            .endOnKey('#')
            .beepStart(true)
            .build();

    TalkAction outro = new TalkAction.Builder("Thank you for your message. Goodbye").build();

    res.type("application/json");

    return new Ncco(intro, record, outro).toJson();
};

O bien, puede construir los objetos y envolverlos en un archivo Ncco sin crear las variables locales adicionales:

return new Ncco(
        new TalkAction.Builder("Please leave a message after the tone, then press #.").build(),
        new RecordAction.Builder()
                .eventUrl(recordingUrl)
                .endOnSilence(3)
                .endOnKey('#')
                .beepStart(true)
                .build(),
        new TalkAction.Builder("Thank you for your message. Goodbye").build()
).toJson();

El objetivo de este cambio era crear una experiencia más intuitiva para crear objetos con muchas propiedades.

Para algunos artículos, como TalkAction con sólo una propiedad text parece más código. Sin embargo, el beneficio se aprecia plenamente cuando tus acciones se vuelven un poco más complejas.

Queremos estudiar otras formas de ayudar en este sentido, tal vez utilizando métodos de fábrica para proporcionar algunos atajos fáciles.

Solicitudes de Number Insight

Nuestro InsightClient tenía bastantes métodos con varias combinaciones de parámetros. A medida que crece el número de opciones para la comprensión de los números, la lista de parámetros sólo va a crecer con él.

Hay una tendencia común en la mayoría de estas actualizaciones y, una vez más, nos decantamos por el patrón constructor.

Antiguo

Para realizar una solicitud estándar de localización de números con información del identificador de llamadas (CNAM), deberá hacer lo siguiente:

StandardInsightResponse response = client.getInsightClient()
        .getStandardNumberInsight(INSIGHT_NUMBER, null, true);

Tenga en cuenta que debe utilizar null en el segundo parámetro para acceder al parámetro cnam parámetro. Esto se siente mal.

Nuevo

Ahora, puedes hacer esto:

StandardInsightRequest request = new StandardInsightRequest.Builder(INSIGHT_NUMBER)
        .cnam(true)
        .build();

StandardInsightResponse response = client.getInsightClient()
        .getStandardNumberInsight(request);

No nos deshicimos del método existente, pero decidimos dejarlo obsoleto en favor del uso de los creadores de solicitudes con eliminación en la próxima versión principal.

He hablado de cómo el patrón constructor puede aumentar la verbosidad del código. Por lo tanto, para los objetos de solicitud de información numérica, también hemos incluido algunos métodos de fábrica estáticos para casos de uso comunes.

Aunque puedes construir objetos de solicitud como este:

AdvancedInsightRequest request = new AdvancedInsightRequest.Builder(INSIGHT_NUMBER).build();

También puede utilizar un método de fábrica estático proporcionado como este:

AdvancedInsightRequest request = AdvancedInsightRequest.withNumber(INSIGHT_NUMBER);

Queremos jugar un poco más con estos métodos de fábrica, especialmente para nuestras nuevas clases de acción.

Limitación del alcance

El flujo de trabajo estándar en las versiones 3.x siempre ha sido pasar por NexmoClient para acceder a otros clientes que dan acceso a la API. Esto sigue siendo así. Sin embargo, la mayoría de nuestros Endpoint y Method fueron declaradas públicas. Esto ha hecho que proporcionar actualizaciones sea un reto, porque no queremos romper la interfaz pública que hemos creado, ya que requiere una actualización importante de la versión.

Como recordatorio, siempre debe utilizar NexmoClient para obtener instancias de otros clientes y acceder a la API:

NexmoClient client = new NexmoClient.Builder()
        .apiKey(NEXMO_API_KEY)
        .apiSecret(NEXMO_API_SECRET)
        .build();

SmsClient smsClient = client.getSmsClient();

TextMessage message = new TextMessage("Acme Inc", TO_NUMBER, "Hello World!");

SmsSubmissionResponse response = smsClient.submitMessage(message);

No debería ser necesario crear una nueva instancia de Endpoint o Method ya que se utilizan internamente y están sujetas a cambios.

Hemos actualizado el ámbito de la mayoría de las clases internas al ámbito por defecto del paquete. Si bien esto no proporciona una verdadera encapsulación, lo estamos haciendo para desalentar cualquier uso de estas clases directamente para que podamos actualizarlas mejor. Esto requirió algunos cambios en los paquetes también, usted puede notar que algunos paquetes han sido eliminados o renombrados.

Conclusión

En primer lugar, ¡sentimos haber roto cosas! Pero esperamos que estos cambios puedan ponernos en mejores condiciones para ofrecer actualizaciones en el futuro.

Si tiene algún problema en el proceso de migración, o nota alguna rareza en la biblioteca de la versión 4, no dude en Enviar un problema y hacérnoslo saber.

No olvide consultar nuestros bloques de construcción actualizados en Desarrollador Nexmo.

Compartir:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Steve CrowAntiguos alumnos de Vonage

Steve se autoproclama matemático y rey de la sátira. También le gustan los galgos, los rompecabezas enrevesados y los juegos de mesa europeos. Cuando no está hablando de matemáticas con gente que no es matemática o de Java con gente que no es de Java, se le puede encontrar tomando café y hackeando código.