Introduction
This page describes the steps for migrating from the previous 51Degrees Device detection API to either version 4 of that API or to the Pipeline API where it is available. In either case, there are breaking changes so this guide should be followed carefully to ensure no problems arise.
Overview
The language that you are using is the most important factor in determining what work is required to migrate to the new API. For some languages and frameworks, such as C, Nginx, or Varnish, there is no Pipeline API so you will be migrating directly to version 4 of the Device Detection API. For other languages such as Java or .NET, you will be migrating from a pure device detection installation to the Pipeline API with a device detection plugin.
Detail
Regardless of which API you are migrating to, there are breaking changes and new features to be aware of. See the following section for detail on the changes needed for your language of choice.
First, add the device detection libraries from the GitHub repo. These can be included using the Visual Studio projects, the CMake projects, or just the files themselves.
The old (V3) device detection API used a single method to initialize a fiftyoneDegreesProvider
. This took all available options as parameters, and was similar for both the 'Pattern' and 'Hash' algorithms.
An equivalent service can be set up using the V4 device detection API. However, the Hash data files have been significantly improved for V4, and are now equivalent or superior to Pattern in every way. As such, Hash is now the only option. It takes the following parameters:
- A resource manager. This is similar to the V3 provider, but provides a generic way of managing resources in a thread-safe manner.
- A configuration structure. This defines the way the data set is used. For example, whether the data set is loaded into memory, or streamed from file.
- A required properties structure. This is a structure which can contain a string or array indicating the properties which should be loaded.
- Data file path. This is the path to the data file which should be loaded.
- An exception structure. This provides a way for internal methods to report exceptions instead of allowing the process to crash.
After setting any configuration options required in the config structure, the data set is initialized using the fiftyoneDegreesHashInitManagerFromFile
, or fiftyoneDegreesHashInitManagerFromMemory
method.
To process a User-Agent with the old API, the fiftyoneDegreesMatch
is called with a workset which has been fetched from the provider. Instead new set of results should be created, then the fiftyoneDegreesResultsHashFromUserAgent
is used in a similar way to fiftyoneDegreesMatch
.
To get a value of a property in the old API, the fiftyoneDegreesSetValues
and fiftyoneDegreesGetString
methods were used. Using the new results structure, values of a property can be retrieved using the fiftyoneDegreesResultsHashGetValueString
method.
Multiple HTTP header matching can follows a similar pattern to single User-Agent matching. Instead of a single string, a fiftyoneDegreesEvidenceKeyValuePairArray
structure is used. Each header is added to the evidence before calling the fiftyoneDegreesResultsHashFromEvidence
method.
Once finished, the results are released using the fiftyoneDegreesResultsHashFree
method, and the data set with the fiftyoneDegreesManagerFree
method.
First, add the device detection libraries from the GitHub repo. These can be included using the Visual Studio projects, the CMake projects, or just the files themselves.
The old (V3) device detection API used a Provider
class initialized with the path to the data file and the required properties, and was similar for Pattern and Hash.
An equivalent service can be set up using the V4 device detection API. Rather than a Provider
, the equivalent class is an "Engine" which extends the EngineBase
base class. An engine is constructed with the following:
- Data file path. This is the path to the data file which should be loaded.
- A configuration instance. This defines the way the data set is used. For example, whether the data set is loaded into memory, or streamed from file.
- A required properties instance. This is a class which can contain a string or array indicating the properties which should be loaded.
After setting any configuration options required in the config structure, the engine is constructed.
To process HTTP headers with the old API, the provider->getMatch
is called with either a single User-Agent string, or a map<string, string>
containing HTTP header names and values. Instead, an EvidenceDeviceDetection
instance should be created, then the engine->process
is used in a similar way to provider->getMatch
. The EvidenceBase
class actually extends map<string, string>
so usage is almost identical. The difference is that the keys will be different to the old API. For example, instead of "User-Agent", the key would be "header.User-Agent". This is because more evidence is supported in the new API (e.g. cookies, query params).
Getting values from a ResultsHash
(or any class extending ResultsBase
) instance is similar to the old API, however the values returned are slightly different. Values follow the nullable pattern. For example, rather than returning a boolean, the results->getValueAsBool
method returns a Value<bool>
type that has hasValue()
and getValue()
methods (in addition to a *
operator which maps to the getValue()
method). Calling getValue()
on a property value that does not have a value will result in an exception. For more detail see the false positive control feature page.
Once finished, the results, evidence, engine, and configuration are freed using their destructors.
Note: If you are working with a ASP.NET or ASP.NET Core web app then check those tabs for a more focused migration guide.
The getting started examples may be a useful reference while migrating.
First, add the FiftyOne.DeviceDetection
NuGet package. Don't forget to remove the old 51Degrees.mobi-core
package and any related packages as well.
The old (V3) device detection API generally had two initialization steps, one to create a DataSet
and one to create a Provider
from that DataSet
. The precise details would depend on:
- Whether you are using the Pattern or Hash algorithm.
- Whether you are loading all the data into memory for better performance or not.
- Other DataSet creation options being used.
There are several ways to set up an equivalent service using the Pipeline API. For example, you could create the device detection engine and then create the Pipeline. However, the easiest method is to use a specific DeviceDetectionPipelineBuilder
. This can be configured using a settings file or directly in code:
The supplied settings will be dependent on your old implementation:
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). Next, change the first line to
.UseCloud
and pass in the resource key you created. - If using
MemoryFactory
rather thatStreamFactory
then change the performance profile toMaxPerformance
. - If using a custom caching configuration, you will need to create the device detection engine first using a
DeviceDetectionHashEngineBuilder
. TheSetCache
method can then be used to supply your custom configuration. Finally, the genericPipelineBuilder
can be used to create a pipeline with the device detection engine added to it. - If you have auto updates disabled then remove the
SetDataUpdateLinceseKey
line and instead useSetAutoUpdate(false)
andSetUpdateOnStartup(false)
.
Regardless of the details above, a configuration file can be used instead:
The JSON configuration file for the same setup as above (on premise, low memory, auto updates enabled) would look like this:
If you are using the 51Degrees cloud then you'll need to add two elements using the builders CloudRequestEngineBuilder
and DeviceDetectionCloudEngineBuilder
. For example:
Once the Pipeline has been created, you'll need to make a few changes to the way data is passed to it. With the old API, you would do something like this:
The Pipeline API is far more flexible so splits this line into 3 parts:
Finally, the way that data is accessed has also changed in several ways.
- Values can now be accessed by strongly typed properties rather than having to remember 'magic strings' (although magic string accessors still work as well).
- Many properties follow the nullable pattern. For example, rather than returning a boolean, the 'IsMobile' property returns a wrapper type that has 'HasValue' and 'Value' accessors. Calling '.Value' on a property that does not have a value will result in an exception. For more detail see the false positive control feature page.
As an example:
becomes:
If you don't mind specifying the return type and dealing with magic strings, You can cut out a step and access properties directly from the flow data if desired. E.g:
This section describes how to migrate from the ASP.NET integration in version 3 of the device detection API to the ASP.NET integration in Pipeline API. Note - The redirect, image optimization and performance monitoring services are no longer supported in the Pipeline API.
The getting started examples may be a useful reference while migrating.
First, add the FiftyOne.DeviceDetection
and FiftyOne.Pipeline.Web
NuGet packages. Don't forget to remove the old 51Degrees.mobi-core
package and any related packages as well.
The main difference is in the configuration file supplied to the Pipeline. This must be in the App_Data folder and can be named:
- pipeline.xml
- pipeline.config (xml format expected)
- pipeline.json
- 51degrees.xml
- 51degrees.config (xml format expected)
- 51degrees.json
This file should follow the usual structure of a pipeline configuration file. For example, a typical device detection configuration would be:
- IMPORTANT:
C:\\Absolute\\Path\\To\\Data\\File\\51Degrees-EnterpriseV4.1.hash
is an absolute path to the data file. Please amend this entry accordingly to your configuration. - Use the performance profile setting to control the trade-off between performance and memory.
LowMemory
is recommended if you're not sure.MaxPerformance
uses the most memory but gives the best performance. - If you have auto updates disabled then remove the
DataUpdateLicenseKey
line and instead use"AutoUpdate": false
and"DataUpdateOnStartup": false
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). See the next snippet below for an example of how to supply this resource key to the Pipeline.
- Modification to
Application_Start
method in the application class from"global.asax.cs"
file to include loading of assemblies required by the pipeline is needed. Again, this is different for cloud and on-premise scenarios. See snippets for both below.
On-premise:
Cloud:
The old v3 web integration used the Request.Browser
functionality that was built in to ASP.NET in order to access result values. The Pipeline integration uses the same approach so you can still do things like:
See the property dictionary for a complete list of the available properties.
If you need to access values specific to the 51Degrees implementation then you can do so by casting to PipelineCapabilities
and accessing the FlowData
instance:
You may also want to access meta data relating to profiles, properties, etc. This data can be obtained from the device detection engine. You can access this by getting the IPipeline
instance from the static WebPipeline
class:
Finally, if you use client-side overrides (which enables detection of Apple models), you'll need to make sure you add a script tag for 51degrees.core.js
. The 51Degrees infrastructure will intercept this request and serve the JavaScript that is used to gather the necessary client side data and pass it back to the server.
You can see examples of this feature in action in the getting started web examples.
This section describes how to migrate from the ASP.NET integration in version 3 of the device detection API to the ASP.NET Core integration in Pipeline API. Note - The redirect, image optimization and performance monitoring services are no longer supported in the Pipeline API.
The getting started examples may be a useful reference while migrating.
First, add the FiftyOne.DeviceDetection
and FiftyOne.Pipeline.Web
NuGet packages. Don't forget to remove the old 51Degrees.mobi-core
package and any related packages as well.
Add the following lines to you 'ConfigureService' method:
Add the following line to the 'Configure' method:
Add a PipelineOptions section to your appsettings.json file and configure appropriately. For example:
- Use the performance profile setting to control the trade-off between performance and memory.
LowMemory
is recommended if you're not sure.MaxPerformance
uses the most memory but gives the best performance. - If you have auto updates disabled then remove the
DataUpdateLicenseKey
line and instead use"AutoUpdate": false
and"DataUpdateOnStartup": false
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). See the next snippet below for an example of how to supply this resource key to the Pipeline.
You can now use dependency injection to access data from the Pipeline in your controllers. For example:
The device properties can then be accessed in the corresponding view. For example:
The FiftyOneJS
component handles the inclusion of client-side evidence. The main use-case for this in device detection is in detecting iPhone and iPad models correctly.
First, add the com.51degrees.device-detection
Maven package.
The old (V3) device detection API generally had two initialization steps, one to create a DataSet
and one to create a Provider
from that DataSet
. The precise details would depend on:
- Whether you are using the Pattern or Hash algorithm.
- Whether you are loading all the data into memory for better performance or not.
- Other DataSet creation options being used.
There are several ways to set up an equivalent service using the Pipeline API. For example, you could create the device detection engine and then create the Pipeline. However, the easiest method is to use a specific DeviceDetectionPipelineBuilder
. This can be configured using a settings file or directly in code:
Settings will be dependent on your old implementation:
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). Next, change the first line to
.useCloud
and pass in the resource key you created. - If using
MemoryFactory
rather thanStreamFactory
then change the performance profile toMaxPerformance
. - If using a custom caching configuration, you will need to create the device detection engine first using a
DeviceDetectionCloudEngineBuilder
(cache is not available on hash engine). ThesetCache
method can then be used to supply your custom configuration. Finally, the genericPipelineBuilder
can be used to create a pipeline with the device detection engine added to it. - If you have auto updates disabled then remove the
setDataUpdateLincenseKey
line and instead usesetAutoUpdate(false)
andsetUpdateOnStartup(false)
Regardless of the details above, a configuration file can be used instead:
The XML configuration file for the same setup as above (on-premise, low memory, auto updates enabled) would look like this:
If you are using the 51Degrees cloud then you'll need to add two elements using the builders CloudRequestEngineBuilder
and DeviceDetectionCloudEngineBuilder
. For example:
Once the Pipeline has been created, you'll need to make a few changes to the way data is passed to it. With the old API, you would do something like this:
The Pipeline API is far more flexible so splits this line into 3 parts:
Finally, the way that data is accessed has also changed in several ways.
- Values can now be accessed by strongly typed properties rather than having to remember 'magic strings' (although magic string accessors still work as well).
- Many properties follow the nullable pattern. For example, rather than returning a boolean, the 'IsMobile' property returns a wrapper type that has 'hasValue' and 'value' accessors. Calling '.gertValue' on a property that does not have a value will result in an exception. For more detail see the false positive control feature page.
As an example:
becomes:
First, add the fiftyone.devicedetection package from NPM.
With the V3 API, a provider could be created with something like this:
Creating a Pipeline with a device detection engine is similar although the options are different. You can use either the generic builder or the specific one for on-premise or cloud separately.
Using the generic builder:
Using the specific on-premise builder:
Using the specific cloud builder:
Settings will be dependent on your old implementation:
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). Next, remove the dataFile line from the configuration and add the resource key you created.
- If you want to trade some performance for system memory then change the performance profile to
MaxPerformance
,Balanced
orLowMemory
- If you want the data file to be updated automatically then remove
autoUpdate: false
and add your license key to the configuration. (Not available for free users)
You can also build a Pipeline from a JSON configuration file:
Where settings.json contains the following:
Once the Pipeline has been created, you'll need to make a few changes to the way data is passed to it and accessed. With the old API, you would do something like this:
In the new API, this is slightly more complicated as it needs to deal with the potential for different types of data in and out.
Accessing the property values is similar in the new API and the old API. The main difference is the addition of the 'hasValue' property that is used to indicate when no match has been found. For more detail on this see the false positive control feature page.
As an example:
Becomes:
First, add the fiftyone_devicedetection package from PyPi.
With the V3 API, a provider could be created with something like this:
Creating a Pipeline with a device detection engine is similar although the options are different:
Settings will be dependent on your old implementation:
- If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). Next, remove the dataFile line from the configuration and add the resource key you created.
- If you want to trade some performance for system memory then change the performance profile to
MaxPerformance
,Balanced
orLowMemory
- If you want the data file to be updated automatically then remove
auto_update: false
and add your license key to the configuration. (Not available for free users)
Once the Pipeline has been created, you'll need to make a few changes to the way data is passed to it and accessed. With the old API, you would do something like this:
In the new API, this is slightly more complicated as it needs to deal with the potential for different types of data in and out.
Accessing the property values is similar in the new API and the old API. The main difference is the addition of the 'hasValue' property that is used to indicate when no match has been found. For more detail on this see the false positive control feature page.
As an example:
Becomes:
If you currently use an on-premise data file with PHP then you will need to get the on-premise version of the PHP API from GitHub.
If you use the cloud version then you can install the fiftyone.devicedetection package from composer.
With the V3 API, a provider could be created with something like this:
If using the 51Degrees cloud service, you'll first need to use the Configurator to create a resource key (this will only take a few minutes and does not require any payment). Next, create a device detection pipeline using the resource key you created:
Once the Pipeline has been created, you'll need to make a few changes to the way data is passed to it and accessed. With the old API, you would do something like this:
In the new API, this is slightly more complicated as it needs to deal with the potential for different types of data in and out.
Accessing the property values is similar in the new API and the old API. The main difference is the addition of the 'hasValue' property that is used to indicate when no match has been found. For more detail on this see the false positive control feature page.
As an example:
Becomes:
Nginx module comes only with an on-premise version, you will need to get the on-premise version of the Nginx API from GitHub.
The implementation of 51Degrees Device Detection V4 module is based on the V3 version and the migration process from V3 to V4 is straightforward. Existing V3 customers can build and use V4 in a similar way as V3. Please make sure to obtain a V4 Hash data file at pricing and be aware of the changes described below.
Removed in V4:
- V4 version supports only one method of detection which is Hash.
- Building V4 module is done as below without specifying the detection method: make install
- Building V4 module is done as below without specifying the detection method:
- The following build options are not available:
FIFTYONEDEGREES_CACHE_KEY_LENGTH
FIFTYONEDEGREES_VALUE_SEPARATOR
- The following directives are removed or changed:
51D_cache
is removed.51D_filePath
changed to51D_file_path
.51D_valueSeparator
changed to51D_value_separator
.
New in V4:
51D_drift
51D_difference
51D_allow_unmatched
51D_use_performance_graph
51D_use_predictive_graph
51D_get_javascript_single
51D_get_javascript_all
51D_set_resp_headers
New requirements in V4:
- Building V4 module requires a compiler that support C11.
- libatomic1
Changes in behaviour:
51D_match_all
also takes evidence from query string and cookie.- Evidence input from query string takes precedence over header evidence.
- For example, if
User-Agent
is supplied via query string, the value will be used instead of the headerUser-Agent
.
- For example, if
- Properties that are overridable can now be overridden by value supplied as input from cookie and query string. Further reads:
- Evidence input from query string takes precedence over header evidence.
- Nginx Integration
Varnish module comes only with an on-premise version. You will need to get the on-premise version of the Varnish API from GitHub.
The implementation of 51Degrees Device Detection V4 module is based on the V3 version and the migration process from V3 to V4 is straightforward. Existing V3 customers can build and use V4 in a similar way as V3. Please make sure to obtain a V4 Hash data file at pricing and be aware of the changes described below.
Removed in V4:
- V4 version supports only one method of detection which is Hash.
- Building V4 module is done as below without specifying the detection method: ./autogen.sh./configure --with-config=release|test --with-datafile=(optional)makesudo make install
- Building V4 module is done as below without specifying the detection method:
- The following build options can now only be set as environment variables:
VARNISHSRC
VMOD_DIR
- The following settings are removed:
set_cache
set_pool
New in V4:
- The build
./configure
command can now be run with the following new flags:--with-config
: set whetherrelease
ortest
module should be built.--with-datafile
: set the data file to be used with tests. This is only applicable when--with-config
is set totest
.
- The following new settings are available to be set before calling
fiftyonedegrees.start
in V4 in addition toset_delimiter
andset_properties
:set_performance_profile
set_drift
set_difference
set_max_concurrency
set_allow_unmatched
set_use_performance_graph
set_use_predictive_graph
- To support automatic requesting relevant User-Agent Client Hints, a new function
set_resp_headers
can be added to thevcl_deliver
block. This only works with browsers that support User-Agent Client Hints. For device detection to work with User-Agent Client Hints, the functionmatch_all
should be used.
New requirements in V4:
- Building V4 module requires a compiler that support C11.
- libatomic1
Further reads: