Vonage Video Transition Guide for Ruby
Transitioning from OpenTok-Ruby-SDK to vonage-ruby-sdk
Introduction
Purpose
The goal of this document is to provide a starting point for transitioning from the OpenTok Ruby Server SDK to the Vonage Ruby Server SDK.
Scope
This document assumes that you are using at least version 4.9.0 or later of the OpenTok Ruby SDK. A initial implementation of the Video API was added to the Ruby Server SDK in version 7.19.0, with additional features implemented in version 7.24.0. However, for your migration we recommend using the current latest version of the Vonage Ruby SDK, which can be found on GitHub or RubyGems.
Assumptions
This guide is intended to be followed by a professional software engineer. At least a basic level of competency with Ruby, common Ruby developer tools, and Git (or other version control system) is assumed. You should be comfortable with reading and writing Ruby code, managing project dependencies, deploying and executing a Ruby project. An introduction to the Ruby language, platform and associated tooling is well beyond the scope of this document.
Resources
The following links are useful for further reading to accompany this document and for reference to anything not covered in this document:
Vonage
- Vonage Video documentation
- Vonage Video API specification
- Vonage Ruby Server SDK Video usage guide
- Vonage Ruby Server SDK Rubydocs
- Vonage Ruby Server SDK Video source code
- Vonage Ruby Server SDK GitHub repo
- Vonage Ruby Server SDK published artifacts on RubyGems
TokBox
- OpenTok API REST reference
- OpenTok Ruby Server SDK documentation
- OpenTok Ruby Server SDK source code
- OpenTok Ruby Server SDK GitHub repo
- OpenTok Ruby Server SDK published artifacts on RubyGems
Planning Your Migration
Before transitioning from OpenTok to Vonage Video, you should consider the scale of the task to set realistic expectations.
Evaluate Impact
In order to evaluate the impact of the migration on your application, there are some questions that you will need to consider.
How much of your application's code depends on the OpenTok SDK? Make a list of all the files in which the SDK is directly used. One way of determining this might be to identify any
.rbfile which contains arequire 'opentok'reference. For example, you can search through the files in your project for the statementrequire 'opentok'using a code editor, IDE, or command-line tool to identify the files affected.How many of the OpenTok SDK's features does your application use? For an example an application that is using the SDK solely to create video sessions and generate client tokens will likely be simpler to migrate than one which is also using archive, broadcast, moderation, and other features.
Which of the OpenTok SDK's features does your application use? Some features may require more effort to migrate than others. See the Key Changes and Considerations section for details of changes between the implementation of the two SDKs.
How tightly-coupled is your application code with the OpenTok SDK? In the context of a Ruby on Rails application, for example, are you invoking methods from the SDK directly in your controller actions, or have you abstracted those method calls in some way (e.g. via use of the Gateway Pattern or Adapter Pattern)?
There may also be other considerations for your specific project that aren't listed above.
Timeline
Take into account the time required to complete the transition. This will depend on a number of factors such as your familiarity with the project and the impact of migrating the project (as described above). It is crucial to have a good test suite in place so that you can verify equivalence between the OpenTok and Vonage Video implementations. The time it will take to complete the transition is roughly proportional to the number of places where the OpenTok SDK is used in your code, as well as the variety of features used, but, as mentioned earlier, some API calls will be simpler to replace than others.
Versioning
OpenTok and Vonage Video are two different products. This makes a progressive migration impossible.
You should create a temporary branch on your version control system for the transition, so that you can make changes gradually and frequently without breaking the existing project. You can also use the existing project's tests as an oracle for correctness. Ideally, you should only merge the transition branch into the main branch once you have completed the conversion.
Key Changes and Considerations
The Vonage Video API has feature parity with OpenTok, and the Ruby SDK is actively maintained to be in line with the API specification. There are, however, some differences between the two SDKs that you should be aware of.
New Features and Standards
Package Structure
Both the OpenTok Ruby SDK and the Vonage Ruby SDK follow the approach for structuring a Ruby gems recommended by Bundler, and so at a high level are similar in structure. There are, however, a couple of key differences:
- The Vonage Ruby SDK uses the zeitwerk library for code autoloading and so follows zeitwerk's conventions for file and directory structure and naming. If you know how Ruby on Rails applications are structured, then you'll already be familiar with these conventions. If not, then it might be worth spending a few minutes familiarizing yourself with them. Considering this structure in terms of the video API implementation:
- The primary
Videoclass is defined in this file - Any classes namespaced under
Video(such asVideo::BroadcastsandVideo::Archives) are defined under this directory.
- The Vonage Ruby SDK implements other Vonage APIs in addition to the Video API. The SDK implements classes that represent each of these API products, and the
Clientclass provides accessors for objects of these classes.
Bearing in mind points 1 and 2 above, starting from the Vonage Client object one or more additional method invocations may be required before you get to method representing the specific video API endpoint that you want to call.
Example 1: Creating a session
Using the OpenTok Ruby SDK might look something like this:
Whereas using the Vonage Ruby SDK might look something like this:
As you would expect with Ruby, you can combine steps 2 and 3 via method chaining:
Example 2: Getting a list of archive recordings
Using the OpenTok Ruby SDK might look something like this:
Whereas using the Vonage Ruby SDK might look something like this:
Again, steps can be combined via method chaining:
A Note on Typing
The Vonage Ruby SDK uses Sorbet for static type checking. To simply the migration from the OpenTok Ruby SDK to the Vonage Ruby SDK, type signatures have not currently been defined for any of the methods in the Video API implementation. Type signatures will be defined for these methods as part of a future release.
A Note on Front-end Changes
The front-end libraries used for your application will be the same as the OpenTok libraries. There is, however, one minor change in terms of their usage.
The interaction between the back-end and front-end will be the same: the SDK will create sessions and also generate tokens for the front-end client libraries to access those sessions. Just as with an OpenTok implementation, the front-end client libraries will expect the back-end server to provide a Session ID and a token. However, with a Vonage implementation the server will also need to provide an Application ID. This Application ID effectively takes the place of the API Key which would be used in an OpenTok implementation, although the front-end client libraries will still label it as an API Key. For more information on Application IDs, see the section on Authentication Changes.
This small change in the interaction between front-end and back-end may require some minor updates to your implementation, for example in your view templates or in the logic that passes data to those view templates.
Package Update
To use the Vonage Ruby SDK you'll need to update your project's dependencies to use the vonage Ruby gem instead of the opentok Ruby gem. You can do this by updating your Gemfile to include the vonage gem:
and then running bundle install.
Authentication Changes
Whereas the opentok gem uses an api_key and api_secret for Authorization, the Video API implementation in the vonage gem uses a JWT. The SDK handles JWT generation in the background for you, but will require an application_id and private_key as credentials in order to generate the token. You can obtain these by setting up a Vonage Application, and generating an application ID and private key for that application. The Vonage Application is also where you can set other settings such as which API products the application is enabled for, callback URLs, storage preferences, etc.
There are a number of ways in which you can create a Vonage Application:
- Via the Developer Dashboard
- Via the Application API
- By using the Vonage CLI
NEVER SHARE OR EXPOSE YOUR PRIVATE KEY!
Should you lose your private key, or should it become compromised in any way, you can generate a new private key by editing the Vonage Application. Updating the Vonage Application with a new key and will automatically invalidate the old key. When editing a Vonage Application via the Dashboard, make sure to click on 'Save' to ensure that the changes take effect.
Your application_id and private_key credentials are then passed in when instantiating a Client object (the example below assumes you have these set as environment variables):
If you have your environment variables named as shown in the above example, you can actually omit the arguments from the new method invocation. The SDK will automatically search the ENV hash for variables of those names and use their values if it finds them. In this case, the following example of instantiating a Vonage::Client object is functionally equivalent to the previous one:
Note that the value for the VONAGE_PRIVATE_KEY can be the path to the location for your private.key file. How you determine the value for this path will depend on how you are deploying your application. If you are deploying your application locally, you can store your private.key file in the root of your project and set the path as private.key. For example, if using dotenv to manage your environment variables, your VONAGE_PRIVATE_KEY definition in your .env file would look like this:
If using the approach described above, make sure you add .env and private.key to your .gitignore file.
If deploying to production using a service such as Render, these types of services usually provide ways of securely storing files such as private keys. The exact method for doing so will depend on the service being used and is beyond the scope of this document.
Method Changes
There are some changes to methods between the OpenTok Ruby SDK and the Video API implementation in the Vonage Ruby SDK.
Method Parameters
Any positional parameters in method signatures have been replaced with keyword parameters in the Vonage SDK.
Method Name Changes
Some methods have been renamed and/or moved, for clarity and/or to better reflect what the method does. These are listed below:
| OpenTok Method Name | Vonage Video Method Name |
|---|---|
opentok.generate_token | video.generate_client_token |
opentok.archives.all | video.archives.list |
opentok.archives.create | video.archives.start |
opentok.archives.delete_by_id | video.archives.delete |
opentok.archives.find | video.archives.info |
opentok.archives.layout | video.archives.change_layout |
opentok.archives.stop_by_id | video.archives.stop |
opentok.broadcasts.all | video.broadcasts.list |
opentok.broadcasts.create | video.broadcasts.start |
opentok.broadcasts.delete_by_id | video.broadcasts.delete |
opentok.broadcasts.find | video.broadcasts.info |
opentok.broadcasts.layout | video.broadcasts.change_layout |
opentok.connections.forceDisconnect | video.moderation.force_disconnect |
opentok.renders.find | video.renders.info |
opentok.signals.send | video.signals.send_to_one and video.signals.send_to_all |
opentok.streams.all | video.streams.list |
opentok.streams.find | video.streams.info |
opentok.streams.force_mute | video.moderation.mute_single_stream |
opentok.streams.force_mute_all | video.moderation.mute_multiple_streams |
opentok.streams.layout | video.streams.change_layout |
Response Objects
Unlike the OpenTok Ruby SDK, the Vonage Ruby SDK doesn't use specific object classes when deserializing the JSON payload of an HTTP response, but instead deserializes responses to generic response objects.
Single Resource Response Objects
Responses where the JSON payload represents a single resource are deserialized by the Vonage Ruby SDK to a generic Vonage::Response object.
At a general level you can use this Vonage::Response object in the same way as you would do the OpenTok::Archive, OpenTok::Broadcast, OpenTok::Stream, etc, objects in that you can access properties from the response payload by calling methods on the object with names equivalent to the property name. For example, if you wanted to start a new archive recording and get its ID from the response, the approach to do this would be broadly similar for the two SDKs.
Example: OpenTok Ruby SDK
Example: Vonage Ruby SDK
One key difference in the implementation of the response objects between the two SDKs is in the use of the facade pattern within the OpenTok Ruby SDK's response objects. The OpenTok SDK's response objects are initialized with a reference to the object which invoked the method that created them. That object in turn carries a reference to an OpenTok::Client object. What this means is that you can invoke methods which interact with some of the Video API endpoints directly on those objects. The response objects in the Vonage Ruby SDK do not provide a direct way of calling methods which wrap Video API endpoints, so you will need to use objects representing the specific feature class as the caller of the method.
Say, for example, you want to stop an archive recording that is currently in progress.
Example: OpenTok Ruby SDK
In the OpenTok SDK you could call the stop method directly on the Archive object returned by the Archives#create method invocation.
Example: Vonage Ruby SDK
In the Vonage SDK you would need to call the stop method on a Video::Archives object and pass in the relevant archive_id as an argument.
Multi Resource Response Objects
Responses where the JSON payload represents a collection of one or more resources are deserialized by the Vonage Ruby SDK to a ListResponse object namespaced under product and then the object type that made the request, for example Vonage::Video::Broadcasts::ListResponse.
Essentially they provide the same functionality as the list response object types from the OpenTok Ruby SDK in that they're iterable collections of individual resource objects. The implementation differs slightly between the SDKs but generally this shouldn't impact the way that you can interact with these objects, and is outlined below more for completeness:
- The
ListResponseobjects in the Vonage Ruby SDK implement aneachmethod and include Ruby'sEnumerablemodule. - The list-type responses in the OpenTok Ruby SDK (e.g.
ArchiveList,BroadcastList, etc) sub-class from Ruby'sArrayclass.
Error Response Objects
Both SDKs define a generic error class which subclass from Ruby's StandardError class, with more specific error classes that subclass from that generic class.
The OpenTok Ruby SDK defines an OpenTok::OpenTokError class and then specific error classes by feature type that subclass from OpenTokError, such as OpenTokArchiveError, OpenTokBroadcastError, OpenTokAuthenticationError, etc. None of these error types implement any additional functionality beyond what StandardError provides.
The Vonage Ruby SDK defines a generic Vonage::Error class and also a Vonage::APIError class which subclasses from Vonage::Error. The APIError class represents errors which result from an HTTP request to a Vonage API endpoint. The SDK then defines a number of more specific error classes, according to the nature of the response received, that subclass from APIError. These classes include Vonage::ClientError (for 4xx responses), Vonage::ServerError (for 5xx responses), and Vonage::AuthenticationError (which subclasses from Vonage::ClientError, and is specifically used for 401 responses).
The APIError class implements some additional logic that provides getter methods for the Net:HTTPResponse object, as well as the response code, headers, and body. You can rescue the exception to access these properties.
Example
Migration Strategies
Incremental Migration
We would recommend an incremental migration, moving from one use case to another, committing every time you end up in a " stable" state. Of course, it would require both OpenTok and Vonage Video API to temporarily coexist.
Please note that, during such incremental process, your application as a whole would not be fully functional anymore as OpenTok and Vonage Video API are two fully different systems.
The exact plan for an incremental approach will depend on how many, and which, Video API features you are using and how you have integrated those features into your application. Although it is not possible to provide implementation-specific guidance in this area, in terms of general approach a possible plan is to update your code feature by feature, and within each feature method by method.
A good place to start would be with any code that instantiates an OpenTok::OpenTok object and replace this with code that instantiates a Vonage::Client object, following the comparison between the two demonstrated in the Package Structure section.
The next step could be update any code which deals with creating sessions, generating client tokens, and passing data to the front-end client libraries.
You could then move on to update in turn any code that implements specific features of the Video API. To use Archives as an example:
- Identify any code where
Archivesare created or interacted with. - Update method invocations so that methods are called on
client.videoinstead ofopentokobjects. - Update any method names that have changed.
- If a method call passes any arguments, update it to use the correct keyword parameters.
- Identify any code where a method is called directly on an
Archiveresponse object, and amend this as outlined in the Response Objects section.
Repeat this process for each feature and method.
There might be additional steps you need to take, such as updating any code where you rescue specific errors. The above list of steps is not exhaustive, but should hopefully provide a good starting point for defining your migration plan.
Gateway/Adapter Pattern
If you are not already using some sort of gateway or adapter pattern as part of your implementation, this migration would be a good opportunity to do so. This would not only help facilitate the migration, but also mean that in general usage your application code would be less tightly coupled with the SDK code.
There are many different approaches to implementing these patterns depending on how your application is structured and/or the framework you are using. It is beyond the scope of this document to provide any specific guidance in this area.
Testing Recommendations
Thorough testing is essential for a smooth transition, both during and after the migration. This includes not only unit tests but also integration and regression testing. It is also worth manually testing your application flow at least once before and after the migration to ensure that your automated tests do what you think they do, or to pick up on any issues that the tests may not have caught. You may even consider creating equivalence tests. The idea is to create a suite which asserts that both the OpenTok and Vonage Video versions of your application do the same thing. These can then be discarded once your transition is complete and the OpenTok version of your application is removed.
Troubleshooting & Support
Support Channels
For general help and discussion on transitioning to Vonage Video, check out the #video-api channel on our Community Slack, where you can get answers from Vonage staff and fellow users. You can also get in touch with us on X @VonageDev.
The primary contact for any issues with the Video API itself is support@api.vonage.com.
If you find a bug with the SDK, please file an issue, with steps to reproduce, on GitHub.