What's Covered
This tutorial illustrates how to use the API in a Web project.
Code and Explanation
package main import ( "fmt" "net/http" "./src/pattern" "html/template" "os" ) // Location of data file. var dataFile = "../data/51Degrees-LiteV3.2.dat" // Global Provider object. var provider FiftyOneDegreesPatternV3.Provider var properties []string // Type definitions which represent the data used to populate the web page // templates. // Object is populated when a match is performed after a request. Used to // inject values into HTML template before serving to requesting device. type exampleTemplate struct{ DatasetPublishedDate string DatasetNextUpdate string DatasetVersion string DatasetName string DatasetDeviceCombinations int DeviceId string MatchMethod int Difference int Rank int DeviceData template.HTML } // Object is populated with a dynamically generated html table containing a // list of properties and their values retrieved from the match object. type usingDetectionTemplate struct{ DeviceData template.HTML } // Function sets up list of available properties in the data set, translating // from SWIG Vector string to go array. func getAvailableProperties() []string{ // Get available properties from the data set. var _properties = provider.GetAvailableProperties() // Get the length of the VectorString and convert to an iterable type. var len = int(_properties.Size()) // Variable to hold list of properties in a native type. var nativeProperties []string // Loop over VectorString of available properties and append them to native // type array. for i := 0; i < len; i++{ nativeProperties = append(nativeProperties, _properties.Get(i)) } return nativeProperties } // Http response handlers. // Index func handler(w http.ResponseWriter, r *http.Request) { templ, err := template.ParseFiles("html/index.html") err = templ.Execute(w, nil) checkError(err) } // Using Detection func usingDetection(w http.ResponseWriter, r *http.Request) { // Get using-detection page HTML tmeplate. templ, err := template.ParseFiles("html/using-detection.html") // Get a match with the request User-Agent. match := provider.GetMatch(r.Header.Get("User-Agent")) // Variable to hold dynamically generated list of properties and their // values. var deviceData string // Dynamically build an HTML list of all the available properties in the // data set and their values retrieved from the match object. for _,property := range properties{ values := match.GetValue(property) if values != "" { deviceData += "<li>" + property + ": " + values + "</li>" }else{ deviceData += "<li>" + property + ": " + "Switch Data Set" + "</li>" } } // Populate usingDetectionTemplate struct d := &usingDetectionTemplate{ DeviceData: template.HTML(deviceData)} // Execute template processor which injects values from type // usingDetectionTemplate and sends response to requesting device. err = templ.Execute(w, d) checkError(err) // Close the match object. FiftyOneDegreesPatternV3.DeleteMatch(match) } // Example page func example(w http.ResponseWriter, r *http.Request) { // Define which properties are displayed on the example page. _properties := []string{"BrowserName", "BrowserVendor", "BrowserVersion", "DeviceType", "HardwareVendor", "IsTablet", "IsMobile", "IsCrawler", "ScreenInchesDiagonal","ScreenPixelsWidth"} // Get example page HTML template. templ, err := template.ParseFiles("html/example.html") // Get a Match with the request User-Agent. match := provider.GetMatch(r.Header.Get("User-Agent")) // Variable to hold dynamically generated table. var deviceData string // Build property table dynamically to inject into template. Get values for // each property and append a row to the HTML table. for _,property := range _properties{ values := match.GetValue(property) if values != "" { deviceData += "<tr><td><a href=\"https://51degrees.com/resources/" + "property-dictionary#"+ property + "\">" + property + "</a>" + "</td><td>" + values + "</td></tr>" }else{ deviceData += "<tr><td><a href=\"https://51degrees.com/resources/" + "property-dictionary#"+ property + "\">" + property + "</a>" + "</td><td>Switch Dataset</td></tr>" } } // Populate exampleTemplate struct d := &exampleTemplate{ DatasetPublishedDate: provider.GetDataSetPublishedDate(), DatasetNextUpdate: provider.GetDataSetNextUpdateDate(), DatasetVersion: provider.GetDataSetFormat(), DatasetName: provider.GetDataSetName(), DatasetDeviceCombinations: provider.GetDataSetDeviceCombinations(), DeviceId: match.GetDeviceId(), MatchMethod: match.GetMethod(), Difference: match.GetDifference(), Rank: match.GetRank(), DeviceData: template.HTML(deviceData)} // Execute template processor which injects values from type exampleTemplate // and sends response to requesting device. err = templ.Execute(w, d) checkError(err) // Release the Match object back to the pool. FiftyOneDegreesPatternV3.DeleteMatch(match) } func main() { fmt.Println("Starting Server...") // Create a new Provider. provider = FiftyOneDegreesPatternV3.NewProvider(dataFile) // Get available properties and assign to to global type. properties = getAvailableProperties() // Set the HTTP handler function. http.HandleFunc("/", handler) http.HandleFunc("/example", example) http.HandleFunc("/using-detection", usingDetection) // Start the Server and bind to port 8080. fmt.Println("Server at port 8080") err := http.ListenAndServe(":8080", nil) checkError(err) } func checkError(err error){ if err != nil { fmt.Println("Fatal error", err.Error()) os.Exit(1) } }
Summary
In this tutorial you have seen how to use the detector in the context of a simple server to retrieve various properties from both a single User-Agent header and multiple HTTP headers. For a full list of properties and the data files they exist in please see the
Property Dictionary
.