{"_id":"588f722bbcace50f0052b9fb","__v":0,"user":"565f3941ea46251700972783","category":{"_id":"588f722bbcace50f0052b9e3","version":"588f722bbcace50f0052b9e1","project":"565f5fa26bafd40d0030a064","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-12-09T21:22:52.427Z","from_sync":false,"order":1,"slug":"user-guide","title":"Reference"},"parentDoc":null,"project":"565f5fa26bafd40d0030a064","version":{"_id":"588f722bbcace50f0052b9e1","project":"565f5fa26bafd40d0030a064","__v":1,"createdAt":"2017-01-30T17:04:43.410Z","releaseDate":"2017-01-30T17:04:43.410Z","categories":["588f722bbcace50f0052b9e2","588f722bbcace50f0052b9e3","588f722bbcace50f0052b9e4","588f722bbcace50f0052b9e5","588f722bbcace50f0052b9e6","588f722bbcace50f0052b9e7"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"5.3.0","version":"5.3.0"},"updates":["57e552b36dec2419008de5e1","57ea8a901780cd170064f27f"],"next":{"pages":[],"description":""},"createdAt":"2015-12-17T19:55:29.225Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":14,"body":"Nanoscale.io enables developers to use familiar JavaScript syntax to define custom business logic within the workflow logic blocks of Proxy Endpoints.  This business logic performs manipulation on Request and Response objects, which contain properties.
 The Request object and properties represent the inbound call from a client at the start of the workflow. The Response object and properties are what is returned to the client after the workflow is completed.\n \nDevelopers can also define common JavaScript variables and functions within [Shared Libraries](doc:shared-libraries) , which can used be across all Proxy Endpoints within an API. Finally, in addition to standard JavaScript functions, nanoscale.io includes the Underscore.js library that provides useful helper functions. nanoscale.io uses Underscore v1.4.4.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Shared Libraries are loaded prior to any custom JavaScript logic defined in the Proxy Endpoint workflow. Therefore, defining a variable or function in workflow logic blocks will override any variables or functions with the same name in a Shared Library.\"\n}\n[/block]\nYou have access to three types of JavaScript Objects:\n\n1. **Standard JavaScript Objects** - To learn more about these objects, please see <a target=\"_blank\" href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\">here</a>*\n2. **Underscrore.js library** - To learn more about these objects, please see <a target=\"_blank\" href=\"http://underscorejs.org/\">here</a>*\n3. **Nanoscale.io Objects** - Specialized nanoscale.io objects described in this section.\n\n** Please note: Nanoscale.io does not have control over these third-party JavaScript libraries, which are subject to on-going changes and updates.* \n\n# Proxy Endpoint Object Types\n\n## 1. Proxy Endpoint Request Object\n\nThe Proxy Endpoint Request Object is initialized by the nanoscale.io server at the beginning of the workflow and loaded from the incoming request.  It can be accessed using the following code name within a workflow logic block.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"request\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nProxy Endpoint Request Object properties:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"id\",\n    \"0-1\": \"`string`\",\n    \"0-2\": \"A unique id generated by nanoscale.io server for each incoming request.\",\n    \"1-0\": \"path\",\n    \"1-1\": \"`string`\",\n    \"1-2\": \"Incoming request path.\",\n    \"2-0\": \"headers\",\n    \"2-1\": \"`object`\",\n    \"2-2\": \"Incoming request headers.\",\n    \"3-0\": \"uri\",\n    \"4-0\": \"query\",\n    \"5-0\": \"form\",\n    \"6-0\": \"body\",\n    \"7-0\": \"method\",\n    \"8-0\": \"vars\",\n    \"9-0\": \"params\",\n    \"3-1\": \"`string`\",\n    \"6-1\": \"`string`\",\n    \"7-1\": \"`string`\",\n    \"4-1\": \"`object`\",\n    \"5-1\": \"`object`\",\n    \"8-1\": \"`object`\",\n    \"9-1\": \"`object`\",\n    \"3-2\": \"Incoming request URI.\",\n    \"4-2\": \"Incoming request URL parameters.\",\n    \"5-2\": \"Incoming request form parameters if Content-Type header is set to **application/x-www-form-urlencoded**.\",\n    \"6-2\": \"Incoming request body.\",\n    \"7-2\": \"Incoming request HTTP method.\",\n    \"8-2\": \"Incoming request path variables.\",\n    \"9-2\": \"Incoming request query, form and vars combined into one hash.\"\n  },\n  \"cols\": 3,\n  \"rows\": 10\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Log the unique request ID\\nlog(\\\"Request ID: \\\" + request.id);\\n \\n// Add format to URL parameters\\nrequest.query.format = \\\"JSON\\\";\\n \\n// Check if client_id is passed in the request\\n\\\"client_id\\\" in request.query;\\n \\n// Check if id exits on the path for a route defined as /events/{id}\\nif (\\\"id\\\" in request.vars) {\\n    log(request.vars[\\\"id\\\"]);\\n}\",\n      \"language\": \"javascript\",\n      \"name\": \"Sample code for Proxy Endpoint Request Object\"\n    }\n  ]\n}\n[/block]\n## 2. Proxy Endpoint Response Object\n\nThe Proxy Endpoint Response Object is initialized by the nanoscale.io server at the beginning of the\nworkflow. It can be accessed using the following code name  within a workflow logic block.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nProxy Endpoint Response Object properties:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"statusCode\",\n    \"0-1\": \"`number`\",\n    \"0-2\": \"Outgoing response status code.\",\n    \"1-0\": \"body\",\n    \"2-0\": \"headers\",\n    \"1-1\": \"`string`\",\n    \"2-1\": \"`object`\",\n    \"1-2\": \"Outgoing response body.\",\n    \"2-2\": \"Outgoing response headers.\",\n    \"3-0\": \"**setJSONBody**\",\n    \"3-1\": \"`function`\",\n    \"3-2\": \"Sets the object as the response's body, formatted as JSON. This method automatically sets the 'Content-Type' header to 'application/json' to match.\",\n    \"4-0\": \"**setJSONBodyPretty**\",\n    \"4-1\": \"`function`\",\n    \"4-2\": \"Sets the object as the response's body, formatted as pretty-printed JSON. This method automatically sets the 'Content-Type' header to 'application/json' to match.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\nHere is a simple way to return JSON to an HTTP request:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Set the response to your JSON.\\nresponse.setJSONBody = {\\\"message\\\":\\\"Hello!\\\"};\",\n      \"language\": \"javascript\",\n      \"name\": \"Proxy Endpoint Response simple\"\n    }\n  ]\n}\n[/block]\nAll this is doing under the hood is:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Set Content-Type\\nresponse.headers[\\\"Content-Type\\\"] = \\\"application/json\\\";\\n \\n// Set status code (this is defaulted to 200).\\nresponse.statusCode = 200;\\n \\n// Set body to JSON data\\nresponse.body = JSON.stringify({\\\"message\\\":\\\"Hello!\\\"});\",\n      \"language\": \"javascript\",\n      \"name\": \"Proxy Endpoint Response under the hood\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"danger\",\n  \"title\": \"Proxy Endpoint Responses\",\n  \"body\": \"The default response object will behave differently depending on the types of remote endpoints used in your proxy flow. Response objects are only initialized for you by default when an HTTP Remote Endpoint is used within your current Proxy Endpoint. In the event that an HTTP response object is initialized for you, it will contain the HTTP response contents of the most recently used HTTP Remote Endpoint.\"\n}\n[/block]\nBy default a Proxy Endpoint will *not* have a response object initialized. In order to initialize your response object, you will want to do the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\",\n      \"language\": \"javascript\",\n      \"name\": \"Proxy Endpoint Response initialization\"\n    }\n  ]\n}\n[/block]\nThis will allow you to then set headers and response body content to return to an entity that is making API requests against your Proxy Endpoint.\n\nIf you are using an HTTP Remote Endpoint type in your Proxy Endpoint, your `request` object will be initialized with that response content. Be warned that you may want to overwrite the `response` with a clean `AP.HTTP.Response` so as to not leak remote response details back to an API requestor.\n\n# Remote Endpoint Object Types\n\n`AP` is the namespace under which all remote endpoint request object types live.\n\nEvery Remote Endpoint object has a request and response object. The name of the of the Remote Endpoint object is determined by the code name set at the Remote Endpoint configuration level *or* by the Endpoint name override value provided at the Proxy Endpoint component level. This means if you have an HTTP Remote Endpoint with a code name of `httpExample` the following is available before the remote request executes:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"httpExample.request = new AP.HTTP.Request();\\nhttpExample.request.headers['Example-Header'] = 'example123';\\n\",\n      \"language\": \"javascript\",\n      \"name\": \"Before request http object\"\n    }\n  ]\n}\n[/block]\nAfter the request has executed, the following is available:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// log the httpExample response body\\nlog(httpExample.response.body);\",\n      \"language\": \"javascript\",\n      \"name\": \"After request http response object\"\n    }\n  ]\n}\n[/block]\nThe following remote endpoint request object properties and methods pertain to their respective remote endpoint types:\n\n<div id=\"remote-endpoint-request-object-http\"></div>\n## HTTP\n\n### HTTP Request\nRemote endpoint request objects of type `HTTP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"headers\",\n    \"1-0\": \"url\",\n    \"2-0\": \"query\",\n    \"3-0\": \"body\",\n    \"4-0\": \"method\",\n    \"0-1\": \"`object`\",\n    \"1-1\": \"`string`\",\n    \"3-1\": \"`string`\",\n    \"4-1\": \"`string`\",\n    \"2-1\": \"`object`\",\n    \"0-2\": \"Remote Endpoint Request headers. NOTE: headers specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over headers set in JavaScript.\",\n    \"1-2\": \"Remote Endpoint Request URL. NOTE: the URL specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over URL set in JavaScript. This property is only used if URL on remote endpoint is blank.\",\n    \"2-2\": \"Remote Endpoint Request URL query parameters. NOTE: query parameters specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over query parameters set in JavaScript.\",\n    \"3-2\": \"Remote Endpoint Request body.\",\n    \"4-2\": \"HTTP method for Remote Endpoint Request.\",\n    \"5-0\": \"**setFormBody** (object)\",\n    \"5-1\": \"`function`\",\n    \"5-2\": \"Sets the object as the request's body, formatted as an HTTP encoded form. This method automatically sets the 'Content-Type' header to 'application/json' to match.\\n\\nThis function has the following parameters:\\n\\n`object` [*object*] - The object to serialize and use as the request body.\"\n  },\n  \"cols\": 3,\n  \"rows\": 6\n}\n[/block]\nHere is an example of how to use a remote endpoint request object of type `HTTP`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Initialize request object for a Remote Endpoint with code name http\\nhttp.request = new AP.HTTP.Request();\\n \\n// Add format to URL parameters\\nhttp.request.query.format = \\\"JSON\\\";\\n \\n// Set method to POST\\nhttp.request.method = \\\"GET\\\";\\n \\n// Set headers to Proxy Endpoint Request headers\\nhttp.request.headers = request.headers;\",\n      \"language\": \"javascript\",\n      \"name\": \"HTTP remote endpoint request object\"\n    }\n  ]\n}\n[/block]\n### HTTP Response\n\nRemote endpoint response objects of type `HTTP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"statusCode\",\n    \"0-1\": \"`integer`\",\n    \"0-2\": \"The status code returned by the remote HTTP service.\",\n    \"1-0\": \"body\",\n    \"1-1\": \"`string`\",\n    \"1-2\": \"The response body returned by the remote HTTP service.\",\n    \"2-0\": \"headers\",\n    \"2-1\": \"`object`\",\n    \"2-2\": \"An array of header keys and values returned by the remote HTTP service.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nHere is an example of how to use a remote endpoint response object of type `HTTP`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// initialize a new response object so we don't leak details.\\nresponse = new AP.HTTP.Response();\\n\\nif (http.response.statusCode == 200) {\\n\\tresponse.setJSONBodyPretty = {\\\"status\\\": \\\"ok\\\"};\\n} else {\\n\\tresponse.statusCode = 400;\\n  response.setJSONBodyPretty = {\\\"status\\\": \\\"oh no!\\\"};\\n}\",\n      \"language\": \"javascript\",\n      \"name\": \"HTTP remote endpoint response object\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-soap\"></div>\n## SOAP\n\n### SOAP Request\n\nRemote endpoint request objects of type `SOAP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"params\",\n    \"1-0\": \"serviceName\",\n    \"2-0\": \"endpointName\",\n    \"3-0\": \"operationName\",\n    \"4-0\": \"actionName\",\n    \"5-0\": \"url\",\n    \"6-0\": \"wssePasswordCredentials\",\n    \"0-1\": \"`object`\",\n    \"1-1\": \"`string`\",\n    \"2-1\": \"`string`\",\n    \"3-1\": \"`string`\",\n    \"4-1\": \"`string`\",\n    \"5-1\": \"`string`\",\n    \"6-1\": \"`object`\",\n    \"0-2\": \"The parameters to pass into the SOAP operation.\",\n    \"1-2\": \"The SOAP service's name, as specified in the WSDL.\",\n    \"2-2\": \"The endpoint name, as specified in the WSDL.\",\n    \"3-2\": \"The operation name to invoke, as specified in the WSDL.\",\n    \"4-2\": \"The action name to invoke, as specified in the WSDL.  Will be ignored if the operationName is present.\",\n    \"5-2\": \"The URL at which to invoke the service.\",\n    \"6-2\": \"The WSSE credentials to use.  Valid value is a hash including a 'username' and 'password' field.\"\n  },\n  \"cols\": 3,\n  \"rows\": 7\n}\n[/block]\nHere is an example of how to use a remote endpoint request object of type `SOAP`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Make the SOAP Request\\nweather.request = new AP.SOAP.Request();\\nweather.request.endpointName = \\\"WeatherSoap12\\\";\\nweather.request.operationName = \\\"GetCityForecastByZIP\\\";\\nweather.request.params = { \\\"ZIP\\\": \\\"22180\\\" };\",\n      \"language\": \"javascript\",\n      \"name\": \"SOAP Before Request Logic\"\n    }\n  ]\n}\n[/block]\n### SOAP Response\n\nRemote endpoint response objects of type `SOAP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"body\",\n    \"0-1\": \"`string`\",\n    \"0-2\": \"The SOAP service response payload.\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\nHere is an example of how to use a remote endpoint response object of type `SOAP`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Retrieve the response data\\nresponseData = JSON.stringify(weather.response.body);\\nresponse.body = responseData;\\nresponse.statusCode = 200;\\nresponse.headers = response.headers || {};\\nresponse.headers['Content-Type'] = 'application/json';\",\n      \"language\": \"javascript\",\n      \"name\": \"SOAP After Request Logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-script\"></div>\n## Script\n\n### Script Request\n\nRemote endpoint request objects of type `Script` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"env\",\n    \"0-1\": \"`object`\",\n    \"0-2\": \"The request's environment variables.\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\nHere is an example of how to use a remote endpoint request object of type `Script`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"script.request = new AP.Script.Request();\\nscript.request.env[\\\"test\\\"] = \\\"hello world\\\";\",\n      \"language\": \"javascript\",\n      \"name\": \"Script Before Request Logic\"\n    }\n  ]\n}\n[/block]\nCalling the remote endpoint will result in the following output:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"echo $test\\n// hello world\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\n### Script Response\n\nRemote endpoint response objects of type `Script` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"stdout\",\n    \"0-1\": \"`string`\",\n    \"0-2\": \"The standard output of the executed script.\",\n    \"1-0\": \"pid\",\n    \"1-1\": \"`int`\",\n    \"1-2\": \"The process id.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\nHere is an example of how to use a remote endpoint response object of type `Script`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\n\\nresponse.body = script.response.stdout;\",\n      \"language\": \"javascript\",\n      \"name\": \"Script response\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-mongo\"></div>\n## Mongo\n\n### Mongo Request\n\nRemote endpoint request objects of type `Mongo` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"**find** (collection, query, limit, skip)\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Performs a query operation on a collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to perform the query on.\\n\\n`query` [*object*] - Defaults to {}. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/query/\\\">http://docs.mongodb.org/master/reference/operator/query</a>\\n\\n`limit` [*number*] - Limit the number of results. Set to 0 for no limit.\\n\\n`skip` [*number*] - Skips some number of results.\",\n    \"1-0\": \"**insert** (collection, document)\",\n    \"1-1\": \"`function`\",\n    \"1-2\": \"Inserts a document into a collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to insert the document into.\\n\\n`document` [*object*] - A document or an array of documents to insert.\",\n    \"2-0\": \"**update** (collection, query, update, options)\",\n    \"2-1\": \"`function`\",\n    \"2-2\": \"Updates the document(s) selected by query in collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to perform the update on.\\n\\n`query` [*object*] - Defaults to {}. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/query/\\\">http://docs.mongodb.org/master/reference/operator/query</a>\\n\\n`update` [*object*] - A document or an update operator. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/update/\\\">http://docs.mongodb.org/master/reference/operator/update</a>\\n\\n`options` [*object*] - Options for the update.\\n\\n`options.upsert` [*boolean*] - Insert a document if the query doesn't match any documents.\\n\\n`options.multi` [*boolean*] - Updates multiple documents matched by the query.\",\n    \"3-0\": \"**save** (collection, document)\",\n    \"3-1\": \"`function`\",\n    \"3-2\": \"Performs an upsert if the document has an id, or performs an insert if the document doesn't have an id.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to save the document in.\\n\\n`document` [*object*] - The document to upsert or insert.\",\n    \"4-0\": \"**remove** (collection, query, justOne)\",\n    \"4-1\": \"`function`\",\n    \"4-2\": \"Removes the document(s) selected by query from the collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - he collection to remove the document(s) from.\\n\\n`query` [*object*] - Defaults to {}. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/query/\\\">http://docs.mongodb.org/master/reference/operator/query</a>\\n\\n`justOne` [*boolean*] - Remove just one document from the collection.\",\n    \"5-0\": \"**drop** (collection)\",\n    \"5-1\": \"`function`\",\n    \"5-2\": \"Delete the entire collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - he collection to drop.\",\n    \"6-0\": \"**aggregate** (collection, stages)\",\n    \"6-1\": \"`function`\",\n    \"6-2\": \"Process documents with an aggregation pipeline.\\n\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to perform the aggregation on.\\n\\n`stages` [*object*] - An array of aggregation pipeline stages. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/aggregation-pipeline/\\\">http://docs.mongodb.org/master/reference/operator/aggregation-pipeline</a>\",\n    \"7-0\": \"**count** (collection, query)\",\n    \"7-2\": \"Count the documents matched by query in collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to perform the count on.\\n\\n`query` [*object*] - Defaults to {}. See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/operator/query/\\\">http://docs.mongodb.org/master/reference/operator/query</a>\",\n    \"7-1\": \"`function`\",\n    \"8-1\": \"`function`\",\n    \"8-0\": \"**mapReduce** (collection, query, scope, map, reduce, finalize, out)\",\n    \"8-2\": \"Perform a map reduce operation on collection.\\n\\nThis function has the following parameters:\\n\\n`collection` [*string*] - The collection to map reduce.\\n\\n`query` [*object*] - Selects documents from collection to map reduce.\\n\\n`scope` [*object*] - Parametrizes the map, reduce, and finalize stages.\\n\\n`map` [*function*] - The map stage.\\n\\n`reduce` [*function*] - The reduce stage.\\n\\n`finalize` [*function*] - The finalize stage.\\n\\n`out` [*object*] - See: <a target=\\\"_blank\\\" href=\\\"http://docs.mongodb.org/master/reference/method/db.collection.mapReduce/#mapreduce-out-mtd\\\">http://docs.mongodb.org/master/reference/method/db.collection.mapReduce/#mapreduce-out-mtd</a>\"\n  },\n  \"cols\": 3,\n  \"rows\": 9\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `find` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.find(\\\"people\\\", {age: {$gt: 20}}, 1, 1);\",\n      \"language\": \"javascript\",\n      \"name\": \".find() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\n### Mongo Response\n\nRemote endpoint response objects of type `Mongo` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"0-2\": \"Data returned by the MongoDB request query/function.\",\n    \"1-0\": \"count\",\n    \"1-1\": \"`integer`\",\n    \"1-2\": \"Count returned by the MongoDB aggregate query/function.\",\n    \"2-0\": \"error\",\n    \"2-1\": \"`query`\",\n    \"2-2\": \"Error string returned from MongoDB for the request.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint response object after using the `find` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the query results\\ndata = JSON.stringify(mongo.response.data);\\n//contains the number of results\\ncount = mongo.response.count;\\n//contains any errors\\nerror = mongo.response.error;\",\n      \"language\": \"javascript\",\n      \"name\": \".find() MongoDB After Request Logic\"\n    }\n  ]\n}\n[/block]\n### Mongo Request/Response Examples\n\nHere is an example of how to use the `Mongo` remote endpoint request object's `insert` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.insert(\\\"people\\\",\\n  [{name: \\\"john\\\", age: 22}, {name: \\\"jane\\\", age: 23}]);\",\n      \"language\": \"javascript\",\n      \"name\": \".insert() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `update` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.update(\\\"people\\\", {_id: data[0]._id}, {$set: {age: 25}});\",\n      \"language\": \"javascript\",\n      \"name\": \".update() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `save` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.save(\\\"people\\\", {name: \\\"joe\\\", age: 22});\",\n      \"language\": \"javascript\",\n      \"name\": \".save() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `remove` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.remove(\\\"people\\\", {age: {$gt: 20}});\",\n      \"language\": \"javascript\",\n      \"name\": \".remove() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `drop` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.drop(\\\"people\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \".drop() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `aggregate` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Insert the data\\nmongo.request = new AP.Mongo.Request();\\nmongo.request.insert(\\\"people\\\",\\n  [{name: \\\"john\\\", age: 22, income:50000}, \\n  {name: \\\"jane\\\", age: 23, income: 30000},\\n  {name: \\\"jill\\\", age: 22, income:60000},\\n  {name: \\\"joe\\\", age: 23, income: 20000}]);\",\n      \"language\": \"javascript\",\n      \"name\": \".insert() MongoDB Before Request Logic for sample data\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Aggregate the data\\nmongo.request = new AP.Mongo.Request();\\nmongo.request.aggregate(\\\"people\\\", {$match: {age: {$gt: 20}}},\\n  {$group: {_id: \\\"$age\\\", total: {$sum: \\\"$income\\\"}}});\",\n      \"language\": \"javascript\",\n      \"name\": \".aggregate() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Access the aggregated data\\ndata = JSON.stringify(mongo.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \".aggregate() MongoDB After Request Logic\"\n    }\n  ]\n}\n[/block]\nHere is an example of how to use the `Mongo` remote endpoint request object's `mapReduce` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nmongo.request.insert(\\\"people\\\",\\n  [{name: \\\"john\\\", age: 22, income:50000}, \\n  {name: \\\"jane\\\", age: 23, income: 30000},\\n  {name: \\\"jill\\\", age: 22, income:60000},\\n  {name: \\\"joe\\\", age: 23, income: 20000}]);\",\n      \"language\": \"javascript\",\n      \"name\": \".insert() MongoDB Before Request Logic for sample data\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mongo.request = new AP.Mongo.Request();\\nfunction map() {\\n  emit(this.age, this.income);\\n}\\nfunction reduce(key, values) {\\n  return Array.sum(values);\\n}\\nfunction finalize(key, value) {\\n  return value - tax;\\n}\\nmongo.request.mapReduce(\\\"people\\\", {age: {$gt: 18}}, {tax: 10000},\\n  map, reduce, finalize);\",\n      \"language\": \"javascript\",\n      \"name\": \".mapReduce() MongoDB Before Request Logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Access the map reduce result data\\ndata = JSON.stringify(mongo.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \".mapReduce() MongoDB After Request Logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-sqlserver\"></div>\n## SQLServer\n\n### SQLServer Request\n\nRemote endpoint request objects of type `SQLServer` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"queryStatement\",\n    \"1-0\": \"executeStatement\",\n    \"2-0\": \"parameters\",\n    \"4-0\": \"**query** (stmt, params)\",\n    \"4-1\": \"`function`\",\n    \"2-1\": \"`array`\",\n    \"0-1\": \"`string`\",\n    \"1-1\": \"`string`\",\n    \"0-2\": \"The request's SQL statement to be executed.  Must be a query that does not modify data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"1-2\": \"The request's SQL statement to be executed.  Must be an update that modifies data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"2-2\": \"The request's parameters to the SQL statement.\",\n    \"4-2\": \"Perform a query on the database. Must be a query that does not modify data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\",\n    \"3-0\": \"**execute** (stmt, params)\",\n    \"3-1\": \"`function`\",\n    \"3-2\": \"Perform an execution statement on the database. Must be an update that modifies data.\\n\\nThis function has the following parameters:\\n\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\nHere is an example of how to use the `SQLServer` remote endpoint request object's `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"sqlserver.request = new AP.SQLServer.Request();\\nsqlserver.request.execute(\\\"INSERT INTO people (name, age) VALUES ('test', 123);\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() SQL Server Before Request Logic\"\n    }\n  ]\n}\n[/block]\n### SQLServer Response\n\nRemote endpoint response objects of type `SQLServer` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"0-2\": \"The result of the SQL query.\",\n    \"1-0\": \"insertId\",\n    \"1-1\": \"`integer`\",\n    \"1-2\": \"The insert ID returned by the SQL Server instance (if applicable).\",\n    \"2-0\": \"rowsAffected\",\n    \"2-1\": \"`integer`\",\n    \"2-2\": \"The number of rows affected by the previous execute statement (if applicable).\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nHere is an example of how to use the `SQLServer` remote endpoint response object after calling the `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the new id of a record if any\\ninsertId = sqlserver.response.insertId;\\n//contains the number of rows affected\\nrowsAffected = sqlserver.response.rowsAffected;\\nresponse.body = JSON.stringify(rowsAffected);\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() SQL Server After Request Logic\"\n    }\n  ]\n}\n[/block]\n### SQLServer Request/Response Examples\n\nHere is an example of how to use the `SQLServer` remote endpoint request object's `query` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"sqlserver.request = new AP.SQLServer.Request();\\nsqlserver.request.query(\\\"SELECT * FROM people WHERE age > ?\\\", [18]);\",\n      \"language\": \"javascript\",\n      \"name\": \".query() SQL Server Before Request Logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the results of the query\\nresponse.body = JSON.stringify(sqlserver.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \".query() SQL Server After Request Logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-mysql\"></div>\n## MySQL\n\n### MySQL Request\n\nRemote endpoint request objects of type `MySQL` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"prototype\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"queryStatement\",\n    \"1-0\": \"executeStatement\",\n    \"2-0\": \"parameters\",\n    \"3-0\": \"**execute** (stmt, params)\",\n    \"4-0\": \"**query** (stmt, params)\",\n    \"0-1\": \"`string`\",\n    \"1-1\": \"`string`\",\n    \"2-1\": \"`array`\",\n    \"3-1\": \"`function`\",\n    \"4-1\": \"`function`\",\n    \"0-2\": \"The request's SQL statement to be executed.  Must be a query that does not modify data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"1-2\": \"The request's SQL statement to be executed.  Must be an update that modifies data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"2-2\": \"The request's parameters to the SQL statement.\",\n    \"3-2\": \"Perform an execution statement on the database. Must be an update that modifies data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\",\n    \"4-2\": \"Perform a query on the database. Must be a query that does not modify data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\nHere is an example of how to use the `MySQL` remote endpoint request object's `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mysql.request = new AP.MySQL.Request();\\nmysql.request.execute(\\\"INSERT INTO people (name, age) VALUES ('test', 123);\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() MySQL Before Request Logic\"\n    }\n  ]\n}\n[/block]\n### MySQL Request\n\nRemote endpoint response objects of type `MySQL` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"0-2\": \"The result of the SQL query.\",\n    \"1-0\": \"insertId\",\n    \"1-1\": \"`integer`\",\n    \"1-2\": \"The insert ID returned by the SQL Server instance (if applicable).\",\n    \"2-0\": \"rowsAffected\",\n    \"2-1\": \"`integer`\",\n    \"2-2\": \"The number of rows affected by the previous execute statement (if applicable).\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nHere is an example of how to use the `MySQL` remote endpoint response object after an `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the new id of a record if any\\ninsertId = mysql.response.insertId;\\n//contains the number of rows affected\\nrowsAffected = mysql.response.rowsAffected;\\nresponse.body = JSON.stringify(rowsAffected);\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() MySQL After Request Logic\"\n    }\n  ]\n}\n[/block]\n### MySQL Request/Response Examples\n\nHere is an example of how to use the `MySQL` remote endpoint request object's `query` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mysql.request = new AP.MySQL.Request();\\nmysql.request.query(\\\"SELECT * FROM people WHERE age > ?\\\", [18]);\",\n      \"language\": \"javascript\",\n      \"name\": \".query() MySQL Before Request Logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the results of the query\\nresponse.body = JSON.stringify(mysql.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \".query() MySQL After Request Logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-postgres\"></div>\n## Postgres\n\n### Postgres Request\n\nRemote endpoint request objects of type `Postgres` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"queryStatement\",\n    \"1-0\": \"executeStatement\",\n    \"2-0\": \"parameters\",\n    \"3-0\": \"**execute** (stmt, params)\",\n    \"4-0\": \"**query** (stmt, params)\",\n    \"0-1\": \"`string`\",\n    \"1-1\": \"`string`\",\n    \"2-1\": \"`array`\",\n    \"3-1\": \"`function`\",\n    \"4-1\": \"`function`\",\n    \"0-2\": \"The request's SQL statement to be executed.  Must be a query that does not modify data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"1-2\": \"The request's SQL statement to be executed.  Must be an update that modifies data.\\n\\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`\",\n    \"2-2\": \"The request's parameters to the SQL statement.\",\n    \"3-2\": \"Perform an execution statement on the database. Must be an update that modifies data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\",\n    \"4-2\": \"Perform a query on the database. Must be a query that does not modify data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's SQL statement to be executed.\\n\\n`params` [*array*] - The request's parameters to the SQL statement.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\nHere is an example of how to use the `Postgres` remote endpoint request object's `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"postgres.request = new AP.Postgres.Request();\\npostgres.request.execute(\\\"INSERT INTO people (name, age) VALUES ('test', 123);\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() Postgres Before Request Logic\"\n    }\n  ]\n}\n[/block]\n### Postgres Response\n\nRemote endpoint response objects of type `Postgres` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"0-2\": \"The result of the SQL query.\",\n    \"1-0\": \"insertId\",\n    \"1-1\": \"`integer`\",\n    \"1-2\": \"The insert ID returned by the SQL Server instance (if applicable).\",\n    \"2-0\": \"rowsAffected\",\n    \"2-1\": \"`integer`\",\n    \"2-2\": \"The number of rows affected by the previous execute statement (if applicable).\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nHere is an example of how to use the `Postgres` remote endpoint response object after calling the `execute` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the new id of a record if any\\ninsertId = postgres.response.insertId;\\n//contains the number of rows affected\\nrowsAffected = postgres.response.rowsAffected;\\nresponse.body = JSON.stringify(rowsAffected);\",\n      \"language\": \"javascript\",\n      \"name\": \".execute() Postgres After Request Logic\"\n    }\n  ]\n}\n[/block]\n### Postgres Request/Response Examples\n\nHere is an example of how to use the `Postgres` remote endpoint request object's `query` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"postgres.request = new AP.Postgres.Request();\\npostgres.request.query(\\\"SELECT * FROM people WHERE age > $1\\\", [\\\"20\\\"]);\",\n      \"language\": \"javascript\",\n      \"name\": \".query()\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//contains the results of the query\\nresponse.body = JSON.stringify(postgres.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \".query() Postgres After Request Logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-ldap\"></div>\n## LDAP\n\n### LDAP Request\n\nRemote endpoint request objects of type `LDAP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-1\": \"`function`\",\n    \"0-0\": \"**search**(baseDistinguishedName, scope, dereferenceAliases, sizeLimit, timeLimit, typesOnly, filter, attributes, controls, opts)\",\n    \"0-2\": \"Perform a search operation.\\n\\nThis function has the following parameters:\\n\\n`baseDistinguishedName` [*string*] - The base distinguished name.\\n\\n`scope` [*string*] - Scope of the search query. Supports the following values: `base`, `single`, `subtree` \\n\\n`dereferenceAliases` [*string*] - Supports the following values: `never`, `search`, `find`, `always`\\n\\n`sizeLimit` [*integer*] - Result size limit on the search results.\\n\\n`timeLimit` [*integer*] - Max time to wait for the search to complete.\\n\\n`typesOnly` [*boolean*] - The finalize stage.\\n\\n`filter` [*string*] - The filter for this search request.\\n\\n`attributes` [*object*] - The search attributes array.\",\n    \"1-0\": \"**bind**(username, password)\",\n    \"1-1\": \"`function`\",\n    \"1-2\": \"Perform a bind operation which authenticates a user for the current session.\\n\\nThis function has the following parameters:\\n\\n`username` [*string*] - The user's username.\\n\\n`password` [*string*] - The user's password.\",\n    \"2-0\": \"**add**(distinguishedName, attributes)\",\n    \"2-1\": \"`function`\",\n    \"2-2\": \"Add entries to the LDAP server.\\n\\nThis function has the following parameters:\\n\\n`distinguishedName` [*string*] - The distinguished name.\\n\\n`attributes` [*string*] - A set of attributes.\",\n    \"3-0\": \"**delete**(distinguishedName)\",\n    \"3-1\": \"`function`\",\n    \"3-2\": \"Delete entries from the LDAP server.\\n\\nThis function has the following parameters:\\n\\n`distinguishedName` [*string*] - The distinguished name.\",\n    \"4-0\": \"**modify**(dinstinguishedName, addAttributes, deleteAttributes, replaceAttributes)\",\n    \"4-1\": \"`function`\",\n    \"4-2\": \"Modify entries in the LDAP server.\\n\\nThis function has the following parameters:\\n\\n`distinguishedName` [*string*] - The distinguished name.\\n\\n`addAttributes` [*object*] - A set of attributes to add.\\n\\n`deleteAttributes` [*object*] - A set of attributes of delete.\\n\\n`replaceAttributes` [*object*] - A set of attributes to replace.\",\n    \"5-0\": \"**compare**(distinguishedName, attribute, value)\",\n    \"5-1\": \"`function`\",\n    \"5-2\": \"Compare an attribute for a distinguished name.\\n\\nThis function has the following parameters:\\n\\n\\n`distinguishedName` [*string*] - The distinguished name.\\n\\n`attribute` [*string*] - The attribute to compare.\\n\\n`value` [*string*] - The value to compare the attribute to.\"\n  },\n  \"cols\": 3,\n  \"rows\": 6\n}\n[/block]\n### LDAP Responses\n\nLDAP responses are more complex than other responses due to the number of request functions that exist.\n\nRemote endpoint response objects of type `LDAP` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"searchResults\",\n    \"0-1\": \"`object`\",\n    \"1-0\": \"compareResult\",\n    \"1-1\": \"`object`\",\n    \"2-0\": \"statusCode\",\n    \"2-1\": \"`integer`\",\n    \"3-0\": \"statusDescription\",\n    \"3-1\": \"`string`\",\n    \"0-2\": \"An object containing many `searchResult` objects that are specific to a search operation.\",\n    \"1-2\": \"An object containing results specific to a compare operation.\\n\\nThis object (when a compare operation is performed) contains the following:\\n\\n`matches` [*boolean*] - If the compare operation results in a match (true/false).\",\n    \"2-2\": \"The status code of the requested operation.\",\n    \"3-2\": \"The status description of the requested operation.\"\n  },\n  \"cols\": 3,\n  \"rows\": 4\n}\n[/block]\nAn LDAP response with `searchResults` will also have `searchResult` objects. These objects have the following properties:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"entries\",\n    \"0-1\": \"`object`\",\n    \"1-0\": \"searchReferences\",\n    \"1-1\": \"`object`\",\n    \"2-0\": \"controls\",\n    \"2-1\": \"`object`\",\n    \"2-2\": \"An array of strings containing the controls.\",\n    \"1-2\": \"An array of search references.\",\n    \"0-2\": \"An array of `entry` objects.\\n\\nThese objects contain:\\n\\n`distinguishedName` [*string*] - The distinguished name.\\n\\n`attributes` [*object*] - An array of objects containing attributes for this entry. These have a `name` [*string*], `values` [*object*] (array of string values), and an array of `byteValues`.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n### LDAP Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\n\\nvar includeByteValues = request.params.includeByteValues === 'true';\\nvar baseDistinguishedName = request.params.baseDistinguishedName || 'dc=nanoscale,dc=io';\\nvar scope = request.params.scope || AP.LDAP.Scope.subtree;\\nvar dereference = request.params.dereferenceAliases || AP.LDAP.DereferenceAliases.always;\\nvar sizeLimit = (typeof request.params.sizeLimit === 'undefined' || request.params.sizeLimit === null) ? 0: parseInt(request.params.sizeLimit);\\nvar timeLimit = (typeof request.params.timeLimit === 'undefined' || request.params.timeLimit === null) ? 0: parseInt(request.params.timeLimit);\\nvar typesOnly = request.params.typesOnly === 'true';\\nvar filter = request.params.filter || \\\"(objectclass=*)\\\";\\nvar attributes = (typeof request.params.attributes === 'undefined' || request.params.attributes === null) ? []: request.params.attributes.split(\\\",\\\");\\nvar controls = null;\\n\\nldap.request.search(\\n  baseDistinguishedName, \\n  scope, \\n  dereference,\\n  sizeLimit, \\n  timeLimit, \\n  typesOnly, \\n  filter, \\n  attributes, \\n  controls,\\n  {\\\"includeByteValues\\\": includeByteValues}\\n);\",\n      \"language\": \"javascript\",\n      \"name\": \"search() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"search() operation after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\n\\nvar username = request.params.username;\\nvar password = request.params.password;\\n\\nldap.request.bind(username, password);\",\n      \"language\": \"javascript\",\n      \"name\": \"bind() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"bind() operation after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\nobj = JSON.parse(request.body)\\nldap.request.add(obj.distinguishedName, obj.attributes);\",\n      \"language\": \"javascript\",\n      \"name\": \"add() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"add() operation after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\nldap.request.delete(request.params.distinguishedName);\",\n      \"language\": \"javascript\",\n      \"name\": \"delete() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"delete() operation after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\nobj = JSON.parse(request.body)\\nldap.request.modify(obj.distinguishedName, obj.addAttributes, obj.deleteAttributes, obj.replaceAttributes);\",\n      \"language\": \"javascript\",\n      \"name\": \"modify() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"modify() operation after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ldap.request = new AP.LDAP.Request();\\n\\nvar distinguishedName = request.params.distinguishedName;\\nvar attribute = request.params.attribute;\\nvar value = request.params.value;\\n\\nldap.request.compare(distinguishedName, attribute, value);\",\n      \"language\": \"javascript\",\n      \"name\": \"compare() operation before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response.headers = {};\\nresponse.headers['Content-Type'] = \\\"application/json\\\";\\nresponse.body = JSON.stringify(ldap.response, null, 4);\\nresponse.statusCode = 200;\",\n      \"language\": \"javascript\",\n      \"name\": \"compare() operation after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-store\"></div>\n## Store\n\n### Store Request\n\nRemote endpoint request objects of type `Store` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"**insert**(collection, object)\",\n    \"0-1\": \"`function`\",\n    \"1-0\": \"**select**(collection, query)\",\n    \"1-1\": \"`function`\",\n    \"2-0\": \"**update**(collection, id, object)\",\n    \"2-1\": \"`function`\",\n    \"3-0\": \"**delete**(collection, query)\",\n    \"3-1\": \"`function`\",\n    \"0-2\": \"Inserts an object into a collection. If the collection does not exist it will be created.\\n\\n`collection` [*string*] - Collection name.\\n\\n`object` [*object*] - The object to be inserted.\",\n    \"1-2\": \"Selects matching objects from a collection based off of the query string.\\n\\n`collection` [*string*] - Collection name.\\n\\n`query` [*string* | *number*] - This can be either a query or a number. If a number, the operation will return the object that has a matching ID. To return *all*, use the string \\\"true\\\".\",\n    \"2-2\": \"Updates a matching object by ID.\\n\\n`collection` [*string*] - Collection name.\\n\\n`id` [*number*] - The object's id.\\n\\n`object` [*object*] - The updated object values.\",\n    \"3-2\": \"Deletes objects from a collection based off of the query results.\\n\\n`collection` [*string*] - Collection name.\\n\\n`query` [*string* | *number*] - This can be either a query or a number. If a number, the operation will return the object that has a matching ID. To return *all*, use the string \\\"true\\\".\"\n  },\n  \"cols\": 3,\n  \"rows\": 4\n}\n[/block]\n### Store Response\n\nRemote endpoint response objects of type `Store` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"`data`\",\n    \"0-1\": \"`object`\",\n    \"1-0\": \"`error`\",\n    \"1-1\": \"`string`\",\n    \"1-2\": \"An error if one occurred due to the previous operation.\",\n    \"0-2\": \"Contains the result set of the previous operation. Usually an array of local store objects.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n### Store Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\nlocal.request.insert(\\\"Tasks\\\", JSON.parse(request.body));\",\n      \"language\": \"javascript\",\n      \"name\": \"insert() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(local.response.data[0]);\",\n      \"language\": \"javascript\",\n      \"name\": \"insert() after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\nlocal.request.select(\\\"Tasks\\\", parseInt(request.params.id));\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation by ID before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(local.response.data[0]);\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation by ID after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\n\\nlocal.request.select(\\\"Dogs\\\", \\\"true\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation for all items in collection before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(local.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation for all items after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\nlocal.request.select(\\\"Tasks\\\", \\\"priority >= $1 order numeric(priority) asc\\\", parseInt(request.params.priority));\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation with contstraints before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(local.response.data);\",\n      \"language\": \"javascript\",\n      \"name\": \"select() operation with contstraints after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\nlocal.request.update(\\\"Tasks\\\", parseInt(request.params.id), JSON.parse(request.body));\",\n      \"language\": \"javascript\",\n      \"name\": \"update() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(local.response.data[0]);\",\n      \"language\": \"javascript\",\n      \"name\": \"update() after request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"local.request = new AP.Store.Request();\\nlocal.request.delete(\\\"Tasks\\\", parseInt(request.params.id));\",\n      \"language\": \"javascript\",\n      \"name\": \"delete() by ID before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.statusCode = 204;\",\n      \"language\": \"javascript\",\n      \"name\": \"delete() by ID after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-smtp\"></div>\n## SMTP\n\n### SMTP Request\n\nRemote endpoint request objects of type `SMTP` have the following properties and methods:\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"send (options)\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Sends the email.\\n\\nThis function has the following parameters:\\n\\n`to` [*array or string*] - array of recipient emails or recipient email as string\\n\\n`cc` [*array or string*] - array of cc emails or cc email as string\\n\\n`bcc` (array or string) - array of bcc emails or bcc email as string\\n\\n`body` [*string*] - email body as string\\n   \\n`subject` [*string*] - email subject as string\\n    \\n`html` [*boolean*] - email body intended layout respects html\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\n### SMTP Response\n\nRemote endpoint response objects of type `SMTP` have the following properties and methods:\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"1-0\": \"error\",\n    \"1-1\": \"`string`\",\n    \"0-2\": \"Data returned by the SMTP request.\",\n    \"1-2\": \"An error if one occurred due to the previous operation.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n### SMTP Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var body = JSON.parse(request.body); \\nsmtp.request = new AP.Smtp.Request();\\nsmtp.request.send({\\n  to: body.to,\\n  cc: body.cc,\\n  bcc: body.bcc,\\n  body: body.body,\\n  subject: body.subject,\\n  html: body.html\\n});\\n\",\n      \"language\": \"javascript\",\n      \"name\": \"send() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty(smtp.response.data);\\n\",\n      \"language\": \"javascript\",\n      \"name\": \"send() after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-redis\"></div>\n## Redis\n\n### Redis Request\n\nRemote endpoint request objects of type `Redis` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"execute (params)\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Performs an execution statement on the database.\\n\\nThe function has the following parameters:\\n\\n`Params` [*array*] – The parameters to pass to the job.\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\n### Redis Response\n\nRemote endpoint response objects of type `Redis` have the following properties and methods:\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-2\": \"Data returned by the Redis request.\",\n    \"0-0\": \"data\",\n    \"0-1\": \"`object`\",\n    \"1-0\": \"statusCode\",\n    \"1-1\": \"`string`\",\n    \"1-2\": \"The status code of the requested operation.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n### Redis Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"redis.request = new AP.Redis.Request();\\nredis.request.execute((request.query.command || '').trim());\",\n      \"language\": \"javascript\",\n      \"name\": \"execute() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//call AP.HTTP.Response so we can use setJSONBodyPretty\\nresponse = new AP.HTTP.Response();\\nif(!redis.response.data) {\\n  response.statusCode = 500;\\n  body = { error: redis.response.data || redis.response.error };\\n} else body = { data: redis.response.data };\\nresponse.setJSONBodyPretty(body);\",\n      \"language\": \"javascript\",\n      \"name\": \"execute() after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-job\"></div>\n## Job\n\n### Job Request\n\nRemote endpoint request objects of type `Job` have the following properties and methods:\n\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"run\",\n    \"0-1\": \"`function`\",\n    \"1-0\": \"schedule\",\n    \"1-1\": \"`function`\",\n    \"0-2\": \"Runs a job.  \\n\\nThe function has the following parameters:\\n\\n`Name` [*string*] – The name of the job.\\n`Params` [*array*] – The parameters to pass to the job.\",\n    \"1-2\": \"Sets a job schedule.  \\n\\nThe function has the following parameters:\\n\\n`Time` [*number*] – time when to schedule the job.\\n`Name` [*string*] – The name of the job.\\n`Params` [*array*] – The parameters to pass to the job.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n### Job Response\n\nRemote endpoint response objects of type `Job` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"statusCode\",\n    \"0-1\": \"`number`\",\n    \"0-2\": \"The status code of the requested operation.\",\n    \"1-0\": \"body\",\n    \"1-1\": \"`string`\",\n    \"1-2\": \"The outgoing response body.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n### Job Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var city = request.params.city;\\nvar country = request.params.country;\\n\\nvar parameters = {\\n  \\\"city\\\": city,\\n  \\\"country\\\": country\\n};\\njobRemoteEndPoint.request = new AP.Job.Request();\\njobRemoteEndPoint.request.run(\\\"FetchWeatherJob\\\", parameters);\",\n      \"language\": \"javascript\",\n      \"name\": \"run() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"jobRemoteEndPoint.request = new AP.Job.Request();\\njobRemoteEndPoint.request.schedule(Math.floor(time.getTime() / 1000), \\\"FetchWeatherJob\\\", parameters);\",\n      \"language\": \"javascript\",\n      \"name\": \"schedule() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//call AP.HTTP.Response so we can use setJSONBodyPretty\\nresponse = new AP.HTTP.Response();\\nresponse.headers[\\\"Content-Type\\\"] = \\\"application/json\\\";\\nresponse.statusCode = 200;\\nvar statusMessage = \\\"Job ran.\\\";\\nresponse.body = JSON.stringify({\\n  \\\"statusMessage\\\": statusMessage\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"run() after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-docker\"></div>\n## Docker\n\n### Docker Request\n\nRemote endpoint request objects of type `Docker` have the following properties and methods:\n\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"execute (cmd, args, env)\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Executes the Docker image.  \\n\\nThe function has the following parameters:\\n\\n`cmd` [*string*] – The command needed to start the Docker image which is taken from the Command property in the Remote endpoint.\\n\\n`args` [*array*] – The parameters to pass to the Docker image.\\n\\n`env` [*string*] - Environment variables to pass to the Docker image.\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\n### Docker Response\n\nRemote endpoint response objects of type `Docker` have the following properties and methods:\n\n\n[block:parameters]\n{\n  \"data\": {\n    \"0-2\": \"The status code of the requested operation.\",\n    \"0-1\": \"`number'\",\n    \"0-0\": \"statusCode\",\n    \"1-0\": \"body\",\n    \"1-1\": \"`object`\",\n    \"1-2\": \"The Docker service response payload.\",\n    \"2-0\": \"header\",\n    \"2-1\": \"`object`\",\n    \"2-2\": \"An array of header keys and values returned by the Docker service.\",\n    \"3-0\": \"log\",\n    \"4-0\": \"error\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\n### Docker Request/Response Examples\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"dockerRemoteEndPoint.request = new AP.Docker.Request();\\n//name(first param) and env (third param) are null so it uses the values set at //remote endpoint\\ndockerRemoteEndPoint.request.execute(null, args, null);\",\n      \"language\": \"javascript\",\n      \"name\": \"execute() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"dockerResponse = dockerRemoteEndPoint.response;\\nresponse = new AP.HTTP.Response();\\nresponse.headers[\\\"Content-Type\\\"] = \\\"application/json\\\";\\nresponse.statusCode = 200;\\nresponse.body = JSON.stringify({\\n  \\\"statusMessage\\\": dockerResponse.error ? \\\"Failed\\\" : \\\"Success\\\",\\n  \\\"logs\\\": dockerResponse.logs\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"execute() after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-push\"></div>\n## Push\n\n### Push Request\n\nRemote endpoint request objects of type `Push` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"subscribe (platform, channel, period, name, token)\",\n    \"1-0\": \"unsubscribe (platform, channel, token)\",\n    \"2-0\": \"push (channel, payload)\",\n    \"2-1\": \"`function`\",\n    \"1-1\": \"`function`\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Subscribes a device to a channel for receiving push notifications.\\n\\nThis function has the following parameters:\\n\\n`platform` [*string*] - The name of the push platform.\\n\\n`channel` [*string*] - The channel to subscribe to or send the payload to.\\n\\n`period` [*number*] - The period of validity for the subscription (in seconds)\\n\\n`name` [*string*] - The name to use for the subscribing device.\\n\\n`token` [*string*] - The token of the subscribing device.\",\n    \"1-2\": \"Unsubscribes a device to a channel so the device will not receive push notifications.\\n\\nThis function has the following parameters:\\n\\n`platform` [*string*] - The name of the push platform.\\n\\n`channel` [*string*] - The channel to subscribe to or send the payload to.\\n\\n`token` [*string*] - The token of the subscribing device.\",\n    \"2-2\": \"Sends a push notification to all devices subscribed to the channel.\\n\\nThis function has the following parameters:\\n\\n`channel` [*string*] - The channel to send push notifications. All devices subscribed to this channel will receive the push notification.\\n\\n`payload` [*object*] - The payload to send to devices.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n\n\n\n<div id=\"remote-endpoint-request-object-cryptographic-keys\"></div>\n## Cryptographic Key\n\n### Cryptographic Key Request\n\nRemote endpoint request objects of type `Cryptographic key` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"generate(keytype, bits, privateKeyName, publicKeyname )\",\n    \"0-1\": \"`function`\",\n    \"0-2\": \"Generates a public/private key pair.  \\n\\nThis function has the following parameters:\\n\\n`keytype` [*string*] - Value indicating the cryptosystem type (“ecdsa”, default “rsa”). \\n    \\n`bits` [*integer*] - Bit length of modulus (should be even, exclude for ECDSA).\\n    \\n`privateKeyName` [*string*] - Name of the private key added to the keystore.\\n   \\n`publicKeyName` [*string*] - Name of the public key added to the keystore.\",\n    \"1-0\": \"create(contents, name, password, pkcs12)\",\n    \"2-0\": \"destroy(name)\",\n    \"1-1\": \"`function`\",\n    \"2-1\": \"`function`\",\n    \"1-2\": \"Create a new key in the keystore with contents provided.\\n\\nThis function has the following parameters:\\n\\n`contents` [*string*] - The base64 encoded key string. \\n    \\n`name` [*string*] - Name of the private or public key created in the keystore.\\n \\n`password` [*string*] - Private key password if necessary.\\n    \\n`pkcs12` [*boolean*] - Indicates if certificate is of pkcs12 format.\",\n    \"2-2\": \"Delete a key from keystone:\\n\\n`name` [*string*] - Name of the key to be deleted from the keystore.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n### Cryptographic Key Response\n\nRemote endpoint response objects of type `Cryptographic Key` have the following properties and methods:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"statusCode\",\n    \"0-1\": \"`number`\",\n    \"1-0\": \"body\",\n    \"1-1\": \"`object`\",\n    \"2-0\": \"error\",\n    \"2-1\": \"`string`\",\n    \"0-2\": \"The status code of the requested operation.\",\n    \"1-2\": \"Outgoing response body.\",\n    \"2-2\": \"Error string returned from the request.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n### Cryptographic Key Request/Response Examples \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"key.request = new AP.Key.Request();\\nvar options = {\\n    privateKeyName: \\\"priv\\\", \\n    publicKeyName: \\\"pub\\\" }; //default 2048 RSA keys\\nkey.request.generate(options);\",\n      \"language\": \"javascript\",\n      \"name\": \"generate() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// generate() RSA with different bit length\\nkey.request = new AP.Key.Request();\\nvar options = {\\n    privateKeyName: \\\"priv4096\\\", \\n    bits: 4096,\\n    publicKeyName: \\\"pub4096\\\" }; //4096 bit RSA key \\nkey.request.generate(options);\",\n      \"language\": \"javascript\",\n      \"name\": \"generate() RSA key before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// generate() ECDSA key, bits are not passed\\nkey.request = new AP.Key.Request();\\nvar options = {\\n    keytype: \\\"ecdsa\\\"\\n    privateKeyName: \\\"privateECDSA\\\", \\n    publicKeyName: \\\"publicECDSA\\\" };\\nkey.request.generate(options);\",\n      \"language\": \"javascript\",\n      \"name\": \"generate() ECDSA key before request logic\"\n    }\n  ]\n}\n[/block]\ngenerate() after request logic\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"key.request = new AP.Key.Request();\\nkey.request.create({\\n\\tcontents: “BASE64_ENCODED_CONTENTS”, \\n\\tname: \\\"my_key\\\", \\n\\tpassword: “secret_if_necessary”, \\n\\tpkcs12: false\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"created() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"key.request = new AP.Key.Request();\\nkey.request.destroy({\\n\\tname: \\\"my_key\\\"\\n});\",\n      \"language\": \"javascript\",\n      \"name\": \"delete() before request logic\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"response = new AP.HTTP.Response();\\nif(key.response.error) {\\n\\tresponse.statusCode = 422;\\n\\tresponse.body = key.response.error;\\n} else response.body = \\\"success\\\";\",\n      \"language\": \"javascript\",\n      \"name\": \"after request logic\"\n    }\n  ]\n}\n[/block]\n<div id=\"remote-endpoint-request-object-sap-hana\"></div>\n## SAP Hana\n\n### SAP Hana Request\n\nRemote endpoint request objects of type `SAP Hana` have the following properties and methods:\n\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"property\",\n    \"h-1\": \"type\",\n    \"h-2\": \"description\",\n    \"0-0\": \"execute (stmt, params)\",\n    \"0-1\": \"`function`\",\n    \"1-1\": \"`function`\",\n    \"1-0\": \"query (stmt, params, resultTypes)\",\n    \"1-2\": \"The request's SQL statement to be executed.  Must be a query that does not modify data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's statement to be executed.\\n\\n`params` [*array*] - The request's parameters passed to SAP Hana.\\n\\n`resultTypes` [*object*] - The result types expected by the query.  The keys represent the column names of the result set, and the values represent a conversion object such as Int or Float.\",\n    \"0-2\": \"The request's SQL statement to be executed.  Must be an update that modifies data.\\n\\nThis function has the following parameters:\\n\\n`stmt` [*string*] - The request's statement to be executed.\\n\\n`params` [*array*] - The request's parameters passed to SAP Hana.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n\n\n# Nanoscale.io Helper Functions and Objects\n\n## Session Object\n\nSession is a hash that is initialized and loaded by nanoscale.io server based on the cookie or server-side session.  The developer can use the following functions to write, read and delete session variables:\n\n- **session.set()**\n\n- **session.get()**\n\n- **session.delete()** \n\nUse isSet() to check if the a session variable exists.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Check if session variable \\\"token\\\" is set\\nsession.isSet(\\\"token\\\");\\n \\n// Set session variable \\\"token\\\" to value \\\"abcde\\\"\\nsession.set(\\\"token\\\", \\\"abcde\\\");\\n \\n// Log session variable \\\"token\\\" using get function\\nlog(session.get(\\\"token\\\"));\\n \\n// Delete session variable \\\"token\\\"\\nsession.delete(\\\"token\\\");\",\n      \"language\": \"javascript\",\n      \"name\": \"Example calls on “token” session variables\"\n    }\n  ]\n}\n[/block]\n## Env Hash\n\nEnv is a hash that is loaded based on environment set on Proxy Endpoint.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Set the Authorization header for Proxy Request using a variable named \\\"my_auth\\\"\\nrequest.header.Authorization = env.my_auth;\",\n      \"language\": \"javascript\",\n      \"name\": \"Sample code for Env Hash\"\n    }\n  ]\n}\n[/block]\n## Log Function\n\nThe Log function can be used to write information to the nanoscale.io log.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Log \\\"hello\\\"\\nlog(“hello”);\",\n      \"language\": \"javascript\",\n      \"name\": \"Sample code for Log Function\"\n    }\n  ]\n}\n[/block]\n## JSON/XML Conversion Function\n\nConvert data from JSON to XML and vice versa.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//convert JSON to XML\\nvar jsonToConvert = JSON.parse(request.body);\\nvar xml = AP.Conversion.toXML(jsonToConvert);\\nresponse.body = xml;\\n\\nAP.Conversion.JSONPath\\n\\n\\n//convert XML to JSON\\nvar xmlToConvert = request.body;\\nvar json = AP.Conversion.toJson(xmlToConvert);\\nresponse.headers['Content-Type'] = 'application/json';\\nresponse.body = json;\\n\\nAP.Conversion.XMLPath\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n## Encrypt and Decrypt Function\n\nDifferent options for encryption and decryption of data using the keys in the keystore\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//encrypt using a key in the nanoscale.io keystore called 'public'\\nresponse.body = AP.Crypto.encrypt(request.body, {key: \\\"public\\\" });\\n\\n//decrypt using a key in the nanoscale.io keystore called 'private' with sha256 algorithm has function\\nresponse.body = AP.Crypto.decrypt(request.body, {key: \\\"private\\\", algorithm: \\\"sha256\\\"});\\n\\n//supported algorithms are:\\n//AP.Crypto.HashingAlgorithms = {\\n//    md5:        \\\"md5\\\",\\n//    sha1:       \\\"sha1\\\",\\n//    sha256:     \\\"sha256\\\",\\n//    sha512:     \\\"sha512\\\",\\n//    sha384:     \\\"sha384\\\",\\n//    sha512_256: \\\"sha512_256\\\",\\n//    sha3_224:   \\\"sha3_224\\\",\\n//    sha3_256:   \\\"sha3_256\\\",\\n//    sha3_384:   \\\"sha3_384\\\",\\n//    sha3_512:   \\\"sha3_512\\\",\\n//}\\n\\n\\n//encrypt using AES encryption algorithm\\nvar plaintext = \\\"let's encrypt this.\\\";\\nvar key = \\\"YWFhYWFhYWFhYWFhYWFhYQ==\\\";\\nvar iv = \\\"YWFhYWJiYmJjY2NjZGRkZA==\\\";\\n\\n//IV is optional, if you do not supply one to the encryption function a suitable \\n//one is generated. IV is not necessary during decryption since it's the first 16\\n//bytes of the payload.\\nvar encrypted = AP.Crypto.Aes.encrypt(plaintext, { key: key, iv: iv }); \\n\\nvar decrypted = AP.Crypto.Aes.decrypt(encrypted, { key: key });\\n\\nresponse = new AP.HTTP.Response();\\nresponse.setJSONBodyPretty({\\n  plaintext: plaintext,\\n  encrypted: String(encrypted),\\n  decrypted: String(decrypted)\\n})\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n## Encoding Function\n\nConvert data to and from Base64 and Hex\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//Convert data to Base64\\n//passing in 'convert to base64'\\nvar valueToEncode = request.params.encode;\\nvar encoded = AP.Encoding.toBase64(valueToEncode);\\n//encodes to 'Y29udmVydCB0byBiYXNlNjQ='\\nresponse.body = encoded;\\n\\n//Convert data from Base64\\n//passing in 'Y29udmVydCB0byBiYXNlNjQ='\\nvar valueToDecode = request.params.decode;\\nvar decoded = AP.Encoding.fromBase64(valueToDecode);\\n//decodes to 'convert to base64'\\nresponse.body = decoded;\\n\\n//Convert data to Hex\\n//passing in 'convert to hex' as param\\nvar valueToHex = request.params.hexit;\\nvar hexed = AP.Encoding.toHex(valueToHex);\\n//converts to '636f6e7665727420746f20686578'\\nresponse.body = hexed;\\n\\n//Convert data from Hex\\n//passing in '636f6e7665727420746f20686578'\\nvar valueFrmHex = request.params.xeh;\\nvar value = AP.Encoding.fromHex(valueFrmHex);\\n//converts to 'conver to hex'\\nresponse.body = value;\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n# Nanoscale.io JS Object Access and Availability\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"To learn more, please refer to the [Request/Response Lifecycle](doc:request-response-lifecycle) section or view the sample API Proxy Endpoint called “**Request and response lifecycle**” that you imported in the Quick Start Guide.\"\n}\n[/block]\nThe following images represent objects and functions, which are available or can be added during the specific steps within the workflow:\n\n## Logic Component Workflow\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/WfmXNplgStCjFUFXXcku_user-guide-javascript-object-reference-logic-component-workflow.png\",\n        \"user-guide-javascript-object-reference-logic-component-workflow.png\",\n        \"1228\",\n        \"587\",\n        \"#6192c7\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n## Single Call Component Workflow\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/6w89VE0S5adAahVkNCuq_user-guide-javascript-object-reference-single-call-component-workflow.png\",\n        \"user-guide-javascript-object-reference-single-call-component-workflow.png\",\n        \"2000\",\n        \"1082\",\n        \"#6093c8\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n*Assume code name is myEndpoint in the above diagram\n\nFor developer's convenience, the editor in the JavaScript logic blocks supports auto-completion:\n\n1. **“Gateway”** -  These are nanoscale.io Objects and Properties\n\n2. **“keyword”** - These are Standard JavaScript Objects and Underscore.js library Objects\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/HVcLZj4DRhqWl5AR4UcI_user-guide-javascript-object-reference-auto-complete.png\",\n        \"user-guide-javascript-object-reference-auto-complete.png\",\n        \"1280\",\n        \"176\",\n        \"#ededed\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Shared Libraries function and variables are not available in auto-complete list, since they are loaded at run-time.\"\n}\n[/block]","excerpt":"","slug":"javascript-object-reference","type":"basic","title":"JavaScript Object Reference"}

JavaScript Object Reference


Nanoscale.io enables developers to use familiar JavaScript syntax to define custom business logic within the workflow logic blocks of Proxy Endpoints. This business logic performs manipulation on Request and Response objects, which contain properties.
 The Request object and properties represent the inbound call from a client at the start of the workflow. The Response object and properties are what is returned to the client after the workflow is completed. Developers can also define common JavaScript variables and functions within [Shared Libraries](doc:shared-libraries) , which can used be across all Proxy Endpoints within an API. Finally, in addition to standard JavaScript functions, nanoscale.io includes the Underscore.js library that provides useful helper functions. nanoscale.io uses Underscore v1.4.4. [block:callout] { "type": "info", "body": "Shared Libraries are loaded prior to any custom JavaScript logic defined in the Proxy Endpoint workflow. Therefore, defining a variable or function in workflow logic blocks will override any variables or functions with the same name in a Shared Library." } [/block] You have access to three types of JavaScript Objects: 1. **Standard JavaScript Objects** - To learn more about these objects, please see <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference">here</a>* 2. **Underscrore.js library** - To learn more about these objects, please see <a target="_blank" href="http://underscorejs.org/">here</a>* 3. **Nanoscale.io Objects** - Specialized nanoscale.io objects described in this section. ** Please note: Nanoscale.io does not have control over these third-party JavaScript libraries, which are subject to on-going changes and updates.* # Proxy Endpoint Object Types ## 1. Proxy Endpoint Request Object The Proxy Endpoint Request Object is initialized by the nanoscale.io server at the beginning of the workflow and loaded from the incoming request. It can be accessed using the following code name within a workflow logic block. [block:code] { "codes": [ { "code": "request", "language": "javascript" } ] } [/block] Proxy Endpoint Request Object properties: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "id", "0-1": "`string`", "0-2": "A unique id generated by nanoscale.io server for each incoming request.", "1-0": "path", "1-1": "`string`", "1-2": "Incoming request path.", "2-0": "headers", "2-1": "`object`", "2-2": "Incoming request headers.", "3-0": "uri", "4-0": "query", "5-0": "form", "6-0": "body", "7-0": "method", "8-0": "vars", "9-0": "params", "3-1": "`string`", "6-1": "`string`", "7-1": "`string`", "4-1": "`object`", "5-1": "`object`", "8-1": "`object`", "9-1": "`object`", "3-2": "Incoming request URI.", "4-2": "Incoming request URL parameters.", "5-2": "Incoming request form parameters if Content-Type header is set to **application/x-www-form-urlencoded**.", "6-2": "Incoming request body.", "7-2": "Incoming request HTTP method.", "8-2": "Incoming request path variables.", "9-2": "Incoming request query, form and vars combined into one hash." }, "cols": 3, "rows": 10 } [/block] [block:code] { "codes": [ { "code": "// Log the unique request ID\nlog(\"Request ID: \" + request.id);\n \n// Add format to URL parameters\nrequest.query.format = \"JSON\";\n \n// Check if client_id is passed in the request\n\"client_id\" in request.query;\n \n// Check if id exits on the path for a route defined as /events/{id}\nif (\"id\" in request.vars) {\n log(request.vars[\"id\"]);\n}", "language": "javascript", "name": "Sample code for Proxy Endpoint Request Object" } ] } [/block] ## 2. Proxy Endpoint Response Object The Proxy Endpoint Response Object is initialized by the nanoscale.io server at the beginning of the workflow. It can be accessed using the following code name within a workflow logic block. [block:code] { "codes": [ { "code": "response", "language": "javascript" } ] } [/block] Proxy Endpoint Response Object properties: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "statusCode", "0-1": "`number`", "0-2": "Outgoing response status code.", "1-0": "body", "2-0": "headers", "1-1": "`string`", "2-1": "`object`", "1-2": "Outgoing response body.", "2-2": "Outgoing response headers.", "3-0": "**setJSONBody**", "3-1": "`function`", "3-2": "Sets the object as the response's body, formatted as JSON. This method automatically sets the 'Content-Type' header to 'application/json' to match.", "4-0": "**setJSONBodyPretty**", "4-1": "`function`", "4-2": "Sets the object as the response's body, formatted as pretty-printed JSON. This method automatically sets the 'Content-Type' header to 'application/json' to match." }, "cols": 3, "rows": 5 } [/block] Here is a simple way to return JSON to an HTTP request: [block:code] { "codes": [ { "code": "// Set the response to your JSON.\nresponse.setJSONBody = {\"message\":\"Hello!\"};", "language": "javascript", "name": "Proxy Endpoint Response simple" } ] } [/block] All this is doing under the hood is: [block:code] { "codes": [ { "code": "// Set Content-Type\nresponse.headers[\"Content-Type\"] = \"application/json\";\n \n// Set status code (this is defaulted to 200).\nresponse.statusCode = 200;\n \n// Set body to JSON data\nresponse.body = JSON.stringify({\"message\":\"Hello!\"});", "language": "javascript", "name": "Proxy Endpoint Response under the hood" } ] } [/block] [block:callout] { "type": "danger", "title": "Proxy Endpoint Responses", "body": "The default response object will behave differently depending on the types of remote endpoints used in your proxy flow. Response objects are only initialized for you by default when an HTTP Remote Endpoint is used within your current Proxy Endpoint. In the event that an HTTP response object is initialized for you, it will contain the HTTP response contents of the most recently used HTTP Remote Endpoint." } [/block] By default a Proxy Endpoint will *not* have a response object initialized. In order to initialize your response object, you will want to do the following: [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();", "language": "javascript", "name": "Proxy Endpoint Response initialization" } ] } [/block] This will allow you to then set headers and response body content to return to an entity that is making API requests against your Proxy Endpoint. If you are using an HTTP Remote Endpoint type in your Proxy Endpoint, your `request` object will be initialized with that response content. Be warned that you may want to overwrite the `response` with a clean `AP.HTTP.Response` so as to not leak remote response details back to an API requestor. # Remote Endpoint Object Types `AP` is the namespace under which all remote endpoint request object types live. Every Remote Endpoint object has a request and response object. The name of the of the Remote Endpoint object is determined by the code name set at the Remote Endpoint configuration level *or* by the Endpoint name override value provided at the Proxy Endpoint component level. This means if you have an HTTP Remote Endpoint with a code name of `httpExample` the following is available before the remote request executes: [block:code] { "codes": [ { "code": "httpExample.request = new AP.HTTP.Request();\nhttpExample.request.headers['Example-Header'] = 'example123';\n", "language": "javascript", "name": "Before request http object" } ] } [/block] After the request has executed, the following is available: [block:code] { "codes": [ { "code": "// log the httpExample response body\nlog(httpExample.response.body);", "language": "javascript", "name": "After request http response object" } ] } [/block] The following remote endpoint request object properties and methods pertain to their respective remote endpoint types: <div id="remote-endpoint-request-object-http"></div> ## HTTP ### HTTP Request Remote endpoint request objects of type `HTTP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "headers", "1-0": "url", "2-0": "query", "3-0": "body", "4-0": "method", "0-1": "`object`", "1-1": "`string`", "3-1": "`string`", "4-1": "`string`", "2-1": "`object`", "0-2": "Remote Endpoint Request headers. NOTE: headers specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over headers set in JavaScript.", "1-2": "Remote Endpoint Request URL. NOTE: the URL specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over URL set in JavaScript. This property is only used if URL on remote endpoint is blank.", "2-2": "Remote Endpoint Request URL query parameters. NOTE: query parameters specified in the Remote Endpoint settings view within the nanoscale.io Admin Web App take precedence over query parameters set in JavaScript.", "3-2": "Remote Endpoint Request body.", "4-2": "HTTP method for Remote Endpoint Request.", "5-0": "**setFormBody** (object)", "5-1": "`function`", "5-2": "Sets the object as the request's body, formatted as an HTTP encoded form. This method automatically sets the 'Content-Type' header to 'application/json' to match.\n\nThis function has the following parameters:\n\n`object` [*object*] - The object to serialize and use as the request body." }, "cols": 3, "rows": 6 } [/block] Here is an example of how to use a remote endpoint request object of type `HTTP`: [block:code] { "codes": [ { "code": "// Initialize request object for a Remote Endpoint with code name http\nhttp.request = new AP.HTTP.Request();\n \n// Add format to URL parameters\nhttp.request.query.format = \"JSON\";\n \n// Set method to POST\nhttp.request.method = \"GET\";\n \n// Set headers to Proxy Endpoint Request headers\nhttp.request.headers = request.headers;", "language": "javascript", "name": "HTTP remote endpoint request object" } ] } [/block] ### HTTP Response Remote endpoint response objects of type `HTTP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "statusCode", "0-1": "`integer`", "0-2": "The status code returned by the remote HTTP service.", "1-0": "body", "1-1": "`string`", "1-2": "The response body returned by the remote HTTP service.", "2-0": "headers", "2-1": "`object`", "2-2": "An array of header keys and values returned by the remote HTTP service." }, "cols": 3, "rows": 3 } [/block] Here is an example of how to use a remote endpoint response object of type `HTTP`: [block:code] { "codes": [ { "code": "// initialize a new response object so we don't leak details.\nresponse = new AP.HTTP.Response();\n\nif (http.response.statusCode == 200) {\n\tresponse.setJSONBodyPretty = {\"status\": \"ok\"};\n} else {\n\tresponse.statusCode = 400;\n response.setJSONBodyPretty = {\"status\": \"oh no!\"};\n}", "language": "javascript", "name": "HTTP remote endpoint response object" } ] } [/block] <div id="remote-endpoint-request-object-soap"></div> ## SOAP ### SOAP Request Remote endpoint request objects of type `SOAP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "params", "1-0": "serviceName", "2-0": "endpointName", "3-0": "operationName", "4-0": "actionName", "5-0": "url", "6-0": "wssePasswordCredentials", "0-1": "`object`", "1-1": "`string`", "2-1": "`string`", "3-1": "`string`", "4-1": "`string`", "5-1": "`string`", "6-1": "`object`", "0-2": "The parameters to pass into the SOAP operation.", "1-2": "The SOAP service's name, as specified in the WSDL.", "2-2": "The endpoint name, as specified in the WSDL.", "3-2": "The operation name to invoke, as specified in the WSDL.", "4-2": "The action name to invoke, as specified in the WSDL.  Will be ignored if the operationName is present.", "5-2": "The URL at which to invoke the service.", "6-2": "The WSSE credentials to use.  Valid value is a hash including a 'username' and 'password' field." }, "cols": 3, "rows": 7 } [/block] Here is an example of how to use a remote endpoint request object of type `SOAP`: [block:code] { "codes": [ { "code": "// Make the SOAP Request\nweather.request = new AP.SOAP.Request();\nweather.request.endpointName = \"WeatherSoap12\";\nweather.request.operationName = \"GetCityForecastByZIP\";\nweather.request.params = { \"ZIP\": \"22180\" };", "language": "javascript", "name": "SOAP Before Request Logic" } ] } [/block] ### SOAP Response Remote endpoint response objects of type `SOAP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "body", "0-1": "`string`", "0-2": "The SOAP service response payload." }, "cols": 3, "rows": 1 } [/block] Here is an example of how to use a remote endpoint response object of type `SOAP`: [block:code] { "codes": [ { "code": "// Retrieve the response data\nresponseData = JSON.stringify(weather.response.body);\nresponse.body = responseData;\nresponse.statusCode = 200;\nresponse.headers = response.headers || {};\nresponse.headers['Content-Type'] = 'application/json';", "language": "javascript", "name": "SOAP After Request Logic" } ] } [/block] <div id="remote-endpoint-request-object-script"></div> ## Script ### Script Request Remote endpoint request objects of type `Script` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "env", "0-1": "`object`", "0-2": "The request's environment variables." }, "cols": 3, "rows": 1 } [/block] Here is an example of how to use a remote endpoint request object of type `Script`: [block:code] { "codes": [ { "code": "script.request = new AP.Script.Request();\nscript.request.env[\"test\"] = \"hello world\";", "language": "javascript", "name": "Script Before Request Logic" } ] } [/block] Calling the remote endpoint will result in the following output: [block:code] { "codes": [ { "code": "echo $test\n// hello world", "language": "shell" } ] } [/block] ### Script Response Remote endpoint response objects of type `Script` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "stdout", "0-1": "`string`", "0-2": "The standard output of the executed script.", "1-0": "pid", "1-1": "`int`", "1-2": "The process id." }, "cols": 3, "rows": 2 } [/block] Here is an example of how to use a remote endpoint response object of type `Script`: [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\n\nresponse.body = script.response.stdout;", "language": "javascript", "name": "Script response" } ] } [/block] <div id="remote-endpoint-request-object-mongo"></div> ## Mongo ### Mongo Request Remote endpoint request objects of type `Mongo` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "**find** (collection, query, limit, skip)", "0-1": "`function`", "0-2": "Performs a query operation on a collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to perform the query on.\n\n`query` [*object*] - Defaults to {}. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/query/\">http://docs.mongodb.org/master/reference/operator/query</a>\n\n`limit` [*number*] - Limit the number of results. Set to 0 for no limit.\n\n`skip` [*number*] - Skips some number of results.", "1-0": "**insert** (collection, document)", "1-1": "`function`", "1-2": "Inserts a document into a collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to insert the document into.\n\n`document` [*object*] - A document or an array of documents to insert.", "2-0": "**update** (collection, query, update, options)", "2-1": "`function`", "2-2": "Updates the document(s) selected by query in collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to perform the update on.\n\n`query` [*object*] - Defaults to {}. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/query/\">http://docs.mongodb.org/master/reference/operator/query</a>\n\n`update` [*object*] - A document or an update operator. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/update/\">http://docs.mongodb.org/master/reference/operator/update</a>\n\n`options` [*object*] - Options for the update.\n\n`options.upsert` [*boolean*] - Insert a document if the query doesn't match any documents.\n\n`options.multi` [*boolean*] - Updates multiple documents matched by the query.", "3-0": "**save** (collection, document)", "3-1": "`function`", "3-2": "Performs an upsert if the document has an id, or performs an insert if the document doesn't have an id.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to save the document in.\n\n`document` [*object*] - The document to upsert or insert.", "4-0": "**remove** (collection, query, justOne)", "4-1": "`function`", "4-2": "Removes the document(s) selected by query from the collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - he collection to remove the document(s) from.\n\n`query` [*object*] - Defaults to {}. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/query/\">http://docs.mongodb.org/master/reference/operator/query</a>\n\n`justOne` [*boolean*] - Remove just one document from the collection.", "5-0": "**drop** (collection)", "5-1": "`function`", "5-2": "Delete the entire collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - he collection to drop.", "6-0": "**aggregate** (collection, stages)", "6-1": "`function`", "6-2": "Process documents with an aggregation pipeline.\n\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to perform the aggregation on.\n\n`stages` [*object*] - An array of aggregation pipeline stages. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/aggregation-pipeline/\">http://docs.mongodb.org/master/reference/operator/aggregation-pipeline</a>", "7-0": "**count** (collection, query)", "7-2": "Count the documents matched by query in collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to perform the count on.\n\n`query` [*object*] - Defaults to {}. See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/operator/query/\">http://docs.mongodb.org/master/reference/operator/query</a>", "7-1": "`function`", "8-1": "`function`", "8-0": "**mapReduce** (collection, query, scope, map, reduce, finalize, out)", "8-2": "Perform a map reduce operation on collection.\n\nThis function has the following parameters:\n\n`collection` [*string*] - The collection to map reduce.\n\n`query` [*object*] - Selects documents from collection to map reduce.\n\n`scope` [*object*] - Parametrizes the map, reduce, and finalize stages.\n\n`map` [*function*] - The map stage.\n\n`reduce` [*function*] - The reduce stage.\n\n`finalize` [*function*] - The finalize stage.\n\n`out` [*object*] - See: <a target=\"_blank\" href=\"http://docs.mongodb.org/master/reference/method/db.collection.mapReduce/#mapreduce-out-mtd\">http://docs.mongodb.org/master/reference/method/db.collection.mapReduce/#mapreduce-out-mtd</a>" }, "cols": 3, "rows": 9 } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `find` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.find(\"people\", {age: {$gt: 20}}, 1, 1);", "language": "javascript", "name": ".find() MongoDB Before Request Logic" } ] } [/block] ### Mongo Response Remote endpoint response objects of type `Mongo` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "data", "0-1": "`object`", "0-2": "Data returned by the MongoDB request query/function.", "1-0": "count", "1-1": "`integer`", "1-2": "Count returned by the MongoDB aggregate query/function.", "2-0": "error", "2-1": "`query`", "2-2": "Error string returned from MongoDB for the request." }, "cols": 3, "rows": 3 } [/block] Here is an example of how to use the `Mongo` remote endpoint response object after using the `find` method: [block:code] { "codes": [ { "code": "//contains the query results\ndata = JSON.stringify(mongo.response.data);\n//contains the number of results\ncount = mongo.response.count;\n//contains any errors\nerror = mongo.response.error;", "language": "javascript", "name": ".find() MongoDB After Request Logic" } ] } [/block] ### Mongo Request/Response Examples Here is an example of how to use the `Mongo` remote endpoint request object's `insert` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.insert(\"people\",\n [{name: \"john\", age: 22}, {name: \"jane\", age: 23}]);", "language": "javascript", "name": ".insert() MongoDB Before Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `update` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.update(\"people\", {_id: data[0]._id}, {$set: {age: 25}});", "language": "javascript", "name": ".update() MongoDB Before Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `save` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.save(\"people\", {name: \"joe\", age: 22});", "language": "javascript", "name": ".save() MongoDB Before Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `remove` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.remove(\"people\", {age: {$gt: 20}});", "language": "javascript", "name": ".remove() MongoDB Before Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `drop` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.drop(\"people\");", "language": "javascript", "name": ".drop() MongoDB Before Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `aggregate` method: [block:code] { "codes": [ { "code": "// Insert the data\nmongo.request = new AP.Mongo.Request();\nmongo.request.insert(\"people\",\n [{name: \"john\", age: 22, income:50000}, \n {name: \"jane\", age: 23, income: 30000},\n {name: \"jill\", age: 22, income:60000},\n {name: \"joe\", age: 23, income: 20000}]);", "language": "javascript", "name": ".insert() MongoDB Before Request Logic for sample data" } ] } [/block] [block:code] { "codes": [ { "code": "// Aggregate the data\nmongo.request = new AP.Mongo.Request();\nmongo.request.aggregate(\"people\", {$match: {age: {$gt: 20}}},\n {$group: {_id: \"$age\", total: {$sum: \"$income\"}}});", "language": "javascript", "name": ".aggregate() MongoDB Before Request Logic" } ] } [/block] [block:code] { "codes": [ { "code": "// Access the aggregated data\ndata = JSON.stringify(mongo.response.data);", "language": "javascript", "name": ".aggregate() MongoDB After Request Logic" } ] } [/block] Here is an example of how to use the `Mongo` remote endpoint request object's `mapReduce` method: [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nmongo.request.insert(\"people\",\n [{name: \"john\", age: 22, income:50000}, \n {name: \"jane\", age: 23, income: 30000},\n {name: \"jill\", age: 22, income:60000},\n {name: \"joe\", age: 23, income: 20000}]);", "language": "javascript", "name": ".insert() MongoDB Before Request Logic for sample data" } ] } [/block] [block:code] { "codes": [ { "code": "mongo.request = new AP.Mongo.Request();\nfunction map() {\n emit(this.age, this.income);\n}\nfunction reduce(key, values) {\n return Array.sum(values);\n}\nfunction finalize(key, value) {\n return value - tax;\n}\nmongo.request.mapReduce(\"people\", {age: {$gt: 18}}, {tax: 10000},\n map, reduce, finalize);", "language": "javascript", "name": ".mapReduce() MongoDB Before Request Logic" } ] } [/block] [block:code] { "codes": [ { "code": "// Access the map reduce result data\ndata = JSON.stringify(mongo.response.data);", "language": "javascript", "name": ".mapReduce() MongoDB After Request Logic" } ] } [/block] <div id="remote-endpoint-request-object-sqlserver"></div> ## SQLServer ### SQLServer Request Remote endpoint request objects of type `SQLServer` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "queryStatement", "1-0": "executeStatement", "2-0": "parameters", "4-0": "**query** (stmt, params)", "4-1": "`function`", "2-1": "`array`", "0-1": "`string`", "1-1": "`string`", "0-2": "The request's SQL statement to be executed.  Must be a query that does not modify data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "1-2": "The request's SQL statement to be executed.  Must be an update that modifies data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "2-2": "The request's parameters to the SQL statement.", "4-2": "Perform a query on the database. Must be a query that does not modify data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement.", "3-0": "**execute** (stmt, params)", "3-1": "`function`", "3-2": "Perform an execution statement on the database. Must be an update that modifies data.\n\nThis function has the following parameters:\n\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement." }, "cols": 3, "rows": 5 } [/block] Here is an example of how to use the `SQLServer` remote endpoint request object's `execute` method: [block:code] { "codes": [ { "code": "sqlserver.request = new AP.SQLServer.Request();\nsqlserver.request.execute(\"INSERT INTO people (name, age) VALUES ('test', 123);\");", "language": "javascript", "name": ".execute() SQL Server Before Request Logic" } ] } [/block] ### SQLServer Response Remote endpoint response objects of type `SQLServer` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "data", "0-1": "`object`", "0-2": "The result of the SQL query.", "1-0": "insertId", "1-1": "`integer`", "1-2": "The insert ID returned by the SQL Server instance (if applicable).", "2-0": "rowsAffected", "2-1": "`integer`", "2-2": "The number of rows affected by the previous execute statement (if applicable)." }, "cols": 3, "rows": 3 } [/block] Here is an example of how to use the `SQLServer` remote endpoint response object after calling the `execute` method: [block:code] { "codes": [ { "code": "//contains the new id of a record if any\ninsertId = sqlserver.response.insertId;\n//contains the number of rows affected\nrowsAffected = sqlserver.response.rowsAffected;\nresponse.body = JSON.stringify(rowsAffected);", "language": "javascript", "name": ".execute() SQL Server After Request Logic" } ] } [/block] ### SQLServer Request/Response Examples Here is an example of how to use the `SQLServer` remote endpoint request object's `query` method: [block:code] { "codes": [ { "code": "sqlserver.request = new AP.SQLServer.Request();\nsqlserver.request.query(\"SELECT * FROM people WHERE age > ?\", [18]);", "language": "javascript", "name": ".query() SQL Server Before Request Logic" } ] } [/block] [block:code] { "codes": [ { "code": "//contains the results of the query\nresponse.body = JSON.stringify(sqlserver.response.data);", "language": "javascript", "name": ".query() SQL Server After Request Logic" } ] } [/block] <div id="remote-endpoint-request-object-mysql"></div> ## MySQL ### MySQL Request Remote endpoint request objects of type `MySQL` have the following properties and methods: [block:parameters] { "data": { "h-0": "prototype", "h-1": "type", "h-2": "description", "0-0": "queryStatement", "1-0": "executeStatement", "2-0": "parameters", "3-0": "**execute** (stmt, params)", "4-0": "**query** (stmt, params)", "0-1": "`string`", "1-1": "`string`", "2-1": "`array`", "3-1": "`function`", "4-1": "`function`", "0-2": "The request's SQL statement to be executed.  Must be a query that does not modify data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "1-2": "The request's SQL statement to be executed.  Must be an update that modifies data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "2-2": "The request's parameters to the SQL statement.", "3-2": "Perform an execution statement on the database. Must be an update that modifies data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement.", "4-2": "Perform a query on the database. Must be a query that does not modify data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement." }, "cols": 3, "rows": 5 } [/block] Here is an example of how to use the `MySQL` remote endpoint request object's `execute` method: [block:code] { "codes": [ { "code": "mysql.request = new AP.MySQL.Request();\nmysql.request.execute(\"INSERT INTO people (name, age) VALUES ('test', 123);\");", "language": "javascript", "name": ".execute() MySQL Before Request Logic" } ] } [/block] ### MySQL Request Remote endpoint response objects of type `MySQL` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "data", "0-1": "`object`", "0-2": "The result of the SQL query.", "1-0": "insertId", "1-1": "`integer`", "1-2": "The insert ID returned by the SQL Server instance (if applicable).", "2-0": "rowsAffected", "2-1": "`integer`", "2-2": "The number of rows affected by the previous execute statement (if applicable)." }, "cols": 3, "rows": 3 } [/block] Here is an example of how to use the `MySQL` remote endpoint response object after an `execute` method: [block:code] { "codes": [ { "code": "//contains the new id of a record if any\ninsertId = mysql.response.insertId;\n//contains the number of rows affected\nrowsAffected = mysql.response.rowsAffected;\nresponse.body = JSON.stringify(rowsAffected);", "language": "javascript", "name": ".execute() MySQL After Request Logic" } ] } [/block] ### MySQL Request/Response Examples Here is an example of how to use the `MySQL` remote endpoint request object's `query` method: [block:code] { "codes": [ { "code": "mysql.request = new AP.MySQL.Request();\nmysql.request.query(\"SELECT * FROM people WHERE age > ?\", [18]);", "language": "javascript", "name": ".query() MySQL Before Request Logic" } ] } [/block] [block:code] { "codes": [ { "code": "//contains the results of the query\nresponse.body = JSON.stringify(mysql.response.data);", "language": "javascript", "name": ".query() MySQL After Request Logic" } ] } [/block] <div id="remote-endpoint-request-object-postgres"></div> ## Postgres ### Postgres Request Remote endpoint request objects of type `Postgres` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "queryStatement", "1-0": "executeStatement", "2-0": "parameters", "3-0": "**execute** (stmt, params)", "4-0": "**query** (stmt, params)", "0-1": "`string`", "1-1": "`string`", "2-1": "`array`", "3-1": "`function`", "4-1": "`function`", "0-2": "The request's SQL statement to be executed.  Must be a query that does not modify data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "1-2": "The request's SQL statement to be executed.  Must be an update that modifies data.\n\nSupports the following: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `stored procedures`, `DDLs`", "2-2": "The request's parameters to the SQL statement.", "3-2": "Perform an execution statement on the database. Must be an update that modifies data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement.", "4-2": "Perform a query on the database. Must be a query that does not modify data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's SQL statement to be executed.\n\n`params` [*array*] - The request's parameters to the SQL statement." }, "cols": 3, "rows": 5 } [/block] Here is an example of how to use the `Postgres` remote endpoint request object's `execute` method: [block:code] { "codes": [ { "code": "postgres.request = new AP.Postgres.Request();\npostgres.request.execute(\"INSERT INTO people (name, age) VALUES ('test', 123);\");", "language": "javascript", "name": ".execute() Postgres Before Request Logic" } ] } [/block] ### Postgres Response Remote endpoint response objects of type `Postgres` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "data", "0-1": "`object`", "0-2": "The result of the SQL query.", "1-0": "insertId", "1-1": "`integer`", "1-2": "The insert ID returned by the SQL Server instance (if applicable).", "2-0": "rowsAffected", "2-1": "`integer`", "2-2": "The number of rows affected by the previous execute statement (if applicable)." }, "cols": 3, "rows": 3 } [/block] Here is an example of how to use the `Postgres` remote endpoint response object after calling the `execute` method: [block:code] { "codes": [ { "code": "//contains the new id of a record if any\ninsertId = postgres.response.insertId;\n//contains the number of rows affected\nrowsAffected = postgres.response.rowsAffected;\nresponse.body = JSON.stringify(rowsAffected);", "language": "javascript", "name": ".execute() Postgres After Request Logic" } ] } [/block] ### Postgres Request/Response Examples Here is an example of how to use the `Postgres` remote endpoint request object's `query` method: [block:code] { "codes": [ { "code": "postgres.request = new AP.Postgres.Request();\npostgres.request.query(\"SELECT * FROM people WHERE age > $1\", [\"20\"]);", "language": "javascript", "name": ".query()" } ] } [/block] [block:code] { "codes": [ { "code": "//contains the results of the query\nresponse.body = JSON.stringify(postgres.response.data);", "language": "javascript", "name": ".query() Postgres After Request Logic" } ] } [/block] <div id="remote-endpoint-request-object-ldap"></div> ## LDAP ### LDAP Request Remote endpoint request objects of type `LDAP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-1": "`function`", "0-0": "**search**(baseDistinguishedName, scope, dereferenceAliases, sizeLimit, timeLimit, typesOnly, filter, attributes, controls, opts)", "0-2": "Perform a search operation.\n\nThis function has the following parameters:\n\n`baseDistinguishedName` [*string*] - The base distinguished name.\n\n`scope` [*string*] - Scope of the search query. Supports the following values: `base`, `single`, `subtree` \n\n`dereferenceAliases` [*string*] - Supports the following values: `never`, `search`, `find`, `always`\n\n`sizeLimit` [*integer*] - Result size limit on the search results.\n\n`timeLimit` [*integer*] - Max time to wait for the search to complete.\n\n`typesOnly` [*boolean*] - The finalize stage.\n\n`filter` [*string*] - The filter for this search request.\n\n`attributes` [*object*] - The search attributes array.", "1-0": "**bind**(username, password)", "1-1": "`function`", "1-2": "Perform a bind operation which authenticates a user for the current session.\n\nThis function has the following parameters:\n\n`username` [*string*] - The user's username.\n\n`password` [*string*] - The user's password.", "2-0": "**add**(distinguishedName, attributes)", "2-1": "`function`", "2-2": "Add entries to the LDAP server.\n\nThis function has the following parameters:\n\n`distinguishedName` [*string*] - The distinguished name.\n\n`attributes` [*string*] - A set of attributes.", "3-0": "**delete**(distinguishedName)", "3-1": "`function`", "3-2": "Delete entries from the LDAP server.\n\nThis function has the following parameters:\n\n`distinguishedName` [*string*] - The distinguished name.", "4-0": "**modify**(dinstinguishedName, addAttributes, deleteAttributes, replaceAttributes)", "4-1": "`function`", "4-2": "Modify entries in the LDAP server.\n\nThis function has the following parameters:\n\n`distinguishedName` [*string*] - The distinguished name.\n\n`addAttributes` [*object*] - A set of attributes to add.\n\n`deleteAttributes` [*object*] - A set of attributes of delete.\n\n`replaceAttributes` [*object*] - A set of attributes to replace.", "5-0": "**compare**(distinguishedName, attribute, value)", "5-1": "`function`", "5-2": "Compare an attribute for a distinguished name.\n\nThis function has the following parameters:\n\n\n`distinguishedName` [*string*] - The distinguished name.\n\n`attribute` [*string*] - The attribute to compare.\n\n`value` [*string*] - The value to compare the attribute to." }, "cols": 3, "rows": 6 } [/block] ### LDAP Responses LDAP responses are more complex than other responses due to the number of request functions that exist. Remote endpoint response objects of type `LDAP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "searchResults", "0-1": "`object`", "1-0": "compareResult", "1-1": "`object`", "2-0": "statusCode", "2-1": "`integer`", "3-0": "statusDescription", "3-1": "`string`", "0-2": "An object containing many `searchResult` objects that are specific to a search operation.", "1-2": "An object containing results specific to a compare operation.\n\nThis object (when a compare operation is performed) contains the following:\n\n`matches` [*boolean*] - If the compare operation results in a match (true/false).", "2-2": "The status code of the requested operation.", "3-2": "The status description of the requested operation." }, "cols": 3, "rows": 4 } [/block] An LDAP response with `searchResults` will also have `searchResult` objects. These objects have the following properties: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "entries", "0-1": "`object`", "1-0": "searchReferences", "1-1": "`object`", "2-0": "controls", "2-1": "`object`", "2-2": "An array of strings containing the controls.", "1-2": "An array of search references.", "0-2": "An array of `entry` objects.\n\nThese objects contain:\n\n`distinguishedName` [*string*] - The distinguished name.\n\n`attributes` [*object*] - An array of objects containing attributes for this entry. These have a `name` [*string*], `values` [*object*] (array of string values), and an array of `byteValues`." }, "cols": 3, "rows": 3 } [/block] ### LDAP Request/Response Examples [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\n\nvar includeByteValues = request.params.includeByteValues === 'true';\nvar baseDistinguishedName = request.params.baseDistinguishedName || 'dc=nanoscale,dc=io';\nvar scope = request.params.scope || AP.LDAP.Scope.subtree;\nvar dereference = request.params.dereferenceAliases || AP.LDAP.DereferenceAliases.always;\nvar sizeLimit = (typeof request.params.sizeLimit === 'undefined' || request.params.sizeLimit === null) ? 0: parseInt(request.params.sizeLimit);\nvar timeLimit = (typeof request.params.timeLimit === 'undefined' || request.params.timeLimit === null) ? 0: parseInt(request.params.timeLimit);\nvar typesOnly = request.params.typesOnly === 'true';\nvar filter = request.params.filter || \"(objectclass=*)\";\nvar attributes = (typeof request.params.attributes === 'undefined' || request.params.attributes === null) ? []: request.params.attributes.split(\",\");\nvar controls = null;\n\nldap.request.search(\n baseDistinguishedName, \n scope, \n dereference,\n sizeLimit, \n timeLimit, \n typesOnly, \n filter, \n attributes, \n controls,\n {\"includeByteValues\": includeByteValues}\n);", "language": "javascript", "name": "search() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "search() operation after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\n\nvar username = request.params.username;\nvar password = request.params.password;\n\nldap.request.bind(username, password);", "language": "javascript", "name": "bind() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "bind() operation after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\nobj = JSON.parse(request.body)\nldap.request.add(obj.distinguishedName, obj.attributes);", "language": "javascript", "name": "add() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "add() operation after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\nldap.request.delete(request.params.distinguishedName);", "language": "javascript", "name": "delete() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "delete() operation after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\nobj = JSON.parse(request.body)\nldap.request.modify(obj.distinguishedName, obj.addAttributes, obj.deleteAttributes, obj.replaceAttributes);", "language": "javascript", "name": "modify() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "modify() operation after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "ldap.request = new AP.LDAP.Request();\n\nvar distinguishedName = request.params.distinguishedName;\nvar attribute = request.params.attribute;\nvar value = request.params.value;\n\nldap.request.compare(distinguishedName, attribute, value);", "language": "javascript", "name": "compare() operation before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response.headers = {};\nresponse.headers['Content-Type'] = \"application/json\";\nresponse.body = JSON.stringify(ldap.response, null, 4);\nresponse.statusCode = 200;", "language": "javascript", "name": "compare() operation after request logic" } ] } [/block] <div id="remote-endpoint-request-object-store"></div> ## Store ### Store Request Remote endpoint request objects of type `Store` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "**insert**(collection, object)", "0-1": "`function`", "1-0": "**select**(collection, query)", "1-1": "`function`", "2-0": "**update**(collection, id, object)", "2-1": "`function`", "3-0": "**delete**(collection, query)", "3-1": "`function`", "0-2": "Inserts an object into a collection. If the collection does not exist it will be created.\n\n`collection` [*string*] - Collection name.\n\n`object` [*object*] - The object to be inserted.", "1-2": "Selects matching objects from a collection based off of the query string.\n\n`collection` [*string*] - Collection name.\n\n`query` [*string* | *number*] - This can be either a query or a number. If a number, the operation will return the object that has a matching ID. To return *all*, use the string \"true\".", "2-2": "Updates a matching object by ID.\n\n`collection` [*string*] - Collection name.\n\n`id` [*number*] - The object's id.\n\n`object` [*object*] - The updated object values.", "3-2": "Deletes objects from a collection based off of the query results.\n\n`collection` [*string*] - Collection name.\n\n`query` [*string* | *number*] - This can be either a query or a number. If a number, the operation will return the object that has a matching ID. To return *all*, use the string \"true\"." }, "cols": 3, "rows": 4 } [/block] ### Store Response Remote endpoint response objects of type `Store` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "`data`", "0-1": "`object`", "1-0": "`error`", "1-1": "`string`", "1-2": "An error if one occurred due to the previous operation.", "0-2": "Contains the result set of the previous operation. Usually an array of local store objects." }, "cols": 3, "rows": 2 } [/block] ### Store Request/Response Examples [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\nlocal.request.insert(\"Tasks\", JSON.parse(request.body));", "language": "javascript", "name": "insert() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(local.response.data[0]);", "language": "javascript", "name": "insert() after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\nlocal.request.select(\"Tasks\", parseInt(request.params.id));", "language": "javascript", "name": "select() operation by ID before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(local.response.data[0]);", "language": "javascript", "name": "select() operation by ID after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\n\nlocal.request.select(\"Dogs\", \"true\");", "language": "javascript", "name": "select() operation for all items in collection before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(local.response.data);", "language": "javascript", "name": "select() operation for all items after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\nlocal.request.select(\"Tasks\", \"priority >= $1 order numeric(priority) asc\", parseInt(request.params.priority));", "language": "javascript", "name": "select() operation with contstraints before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(local.response.data);", "language": "javascript", "name": "select() operation with contstraints after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\nlocal.request.update(\"Tasks\", parseInt(request.params.id), JSON.parse(request.body));", "language": "javascript", "name": "update() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(local.response.data[0]);", "language": "javascript", "name": "update() after request logic" } ] } [/block] [block:code] { "codes": [ { "code": "local.request = new AP.Store.Request();\nlocal.request.delete(\"Tasks\", parseInt(request.params.id));", "language": "javascript", "name": "delete() by ID before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.statusCode = 204;", "language": "javascript", "name": "delete() by ID after request logic" } ] } [/block] <div id="remote-endpoint-request-object-smtp"></div> ## SMTP ### SMTP Request Remote endpoint request objects of type `SMTP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "send (options)", "0-1": "`function`", "0-2": "Sends the email.\n\nThis function has the following parameters:\n\n`to` [*array or string*] - array of recipient emails or recipient email as string\n\n`cc` [*array or string*] - array of cc emails or cc email as string\n\n`bcc` (array or string) - array of bcc emails or bcc email as string\n\n`body` [*string*] - email body as string\n \n`subject` [*string*] - email subject as string\n \n`html` [*boolean*] - email body intended layout respects html" }, "cols": 3, "rows": 1 } [/block] ### SMTP Response Remote endpoint response objects of type `SMTP` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "data", "0-1": "`object`", "1-0": "error", "1-1": "`string`", "0-2": "Data returned by the SMTP request.", "1-2": "An error if one occurred due to the previous operation." }, "cols": 3, "rows": 2 } [/block] ### SMTP Request/Response Examples [block:code] { "codes": [ { "code": "var body = JSON.parse(request.body); \nsmtp.request = new AP.Smtp.Request();\nsmtp.request.send({\n to: body.to,\n cc: body.cc,\n bcc: body.bcc,\n body: body.body,\n subject: body.subject,\n html: body.html\n});\n", "language": "javascript", "name": "send() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nresponse.setJSONBodyPretty(smtp.response.data);\n", "language": "javascript", "name": "send() after request logic" } ] } [/block] <div id="remote-endpoint-request-object-redis"></div> ## Redis ### Redis Request Remote endpoint request objects of type `Redis` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "execute (params)", "0-1": "`function`", "0-2": "Performs an execution statement on the database.\n\nThe function has the following parameters:\n\n`Params` [*array*] – The parameters to pass to the job." }, "cols": 3, "rows": 1 } [/block] ### Redis Response Remote endpoint response objects of type `Redis` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-2": "Data returned by the Redis request.", "0-0": "data", "0-1": "`object`", "1-0": "statusCode", "1-1": "`string`", "1-2": "The status code of the requested operation." }, "cols": 3, "rows": 2 } [/block] ### Redis Request/Response Examples [block:code] { "codes": [ { "code": "redis.request = new AP.Redis.Request();\nredis.request.execute((request.query.command || '').trim());", "language": "javascript", "name": "execute() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "//call AP.HTTP.Response so we can use setJSONBodyPretty\nresponse = new AP.HTTP.Response();\nif(!redis.response.data) {\n response.statusCode = 500;\n body = { error: redis.response.data || redis.response.error };\n} else body = { data: redis.response.data };\nresponse.setJSONBodyPretty(body);", "language": "javascript", "name": "execute() after request logic" } ] } [/block] <div id="remote-endpoint-request-object-job"></div> ## Job ### Job Request Remote endpoint request objects of type `Job` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "run", "0-1": "`function`", "1-0": "schedule", "1-1": "`function`", "0-2": "Runs a job. \n\nThe function has the following parameters:\n\n`Name` [*string*] – The name of the job.\n`Params` [*array*] – The parameters to pass to the job.", "1-2": "Sets a job schedule. \n\nThe function has the following parameters:\n\n`Time` [*number*] – time when to schedule the job.\n`Name` [*string*] – The name of the job.\n`Params` [*array*] – The parameters to pass to the job." }, "cols": 3, "rows": 2 } [/block] ### Job Response Remote endpoint response objects of type `Job` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "statusCode", "0-1": "`number`", "0-2": "The status code of the requested operation.", "1-0": "body", "1-1": "`string`", "1-2": "The outgoing response body." }, "cols": 3, "rows": 2 } [/block] ### Job Request/Response Examples [block:code] { "codes": [ { "code": "var city = request.params.city;\nvar country = request.params.country;\n\nvar parameters = {\n \"city\": city,\n \"country\": country\n};\njobRemoteEndPoint.request = new AP.Job.Request();\njobRemoteEndPoint.request.run(\"FetchWeatherJob\", parameters);", "language": "javascript", "name": "run() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "jobRemoteEndPoint.request = new AP.Job.Request();\njobRemoteEndPoint.request.schedule(Math.floor(time.getTime() / 1000), \"FetchWeatherJob\", parameters);", "language": "javascript", "name": "schedule() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "//call AP.HTTP.Response so we can use setJSONBodyPretty\nresponse = new AP.HTTP.Response();\nresponse.headers[\"Content-Type\"] = \"application/json\";\nresponse.statusCode = 200;\nvar statusMessage = \"Job ran.\";\nresponse.body = JSON.stringify({\n \"statusMessage\": statusMessage\n});", "language": "javascript", "name": "run() after request logic" } ] } [/block] <div id="remote-endpoint-request-object-docker"></div> ## Docker ### Docker Request Remote endpoint request objects of type `Docker` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "execute (cmd, args, env)", "0-1": "`function`", "0-2": "Executes the Docker image. \n\nThe function has the following parameters:\n\n`cmd` [*string*] – The command needed to start the Docker image which is taken from the Command property in the Remote endpoint.\n\n`args` [*array*] – The parameters to pass to the Docker image.\n\n`env` [*string*] - Environment variables to pass to the Docker image." }, "cols": 3, "rows": 1 } [/block] ### Docker Response Remote endpoint response objects of type `Docker` have the following properties and methods: [block:parameters] { "data": { "0-2": "The status code of the requested operation.", "0-1": "`number'", "0-0": "statusCode", "1-0": "body", "1-1": "`object`", "1-2": "The Docker service response payload.", "2-0": "header", "2-1": "`object`", "2-2": "An array of header keys and values returned by the Docker service.", "3-0": "log", "4-0": "error" }, "cols": 3, "rows": 5 } [/block] ### Docker Request/Response Examples [block:code] { "codes": [ { "code": "dockerRemoteEndPoint.request = new AP.Docker.Request();\n//name(first param) and env (third param) are null so it uses the values set at //remote endpoint\ndockerRemoteEndPoint.request.execute(null, args, null);", "language": "javascript", "name": "execute() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "dockerResponse = dockerRemoteEndPoint.response;\nresponse = new AP.HTTP.Response();\nresponse.headers[\"Content-Type\"] = \"application/json\";\nresponse.statusCode = 200;\nresponse.body = JSON.stringify({\n \"statusMessage\": dockerResponse.error ? \"Failed\" : \"Success\",\n \"logs\": dockerResponse.logs\n});", "language": "javascript", "name": "execute() after request logic" } ] } [/block] <div id="remote-endpoint-request-object-push"></div> ## Push ### Push Request Remote endpoint request objects of type `Push` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "subscribe (platform, channel, period, name, token)", "1-0": "unsubscribe (platform, channel, token)", "2-0": "push (channel, payload)", "2-1": "`function`", "1-1": "`function`", "0-1": "`function`", "0-2": "Subscribes a device to a channel for receiving push notifications.\n\nThis function has the following parameters:\n\n`platform` [*string*] - The name of the push platform.\n\n`channel` [*string*] - The channel to subscribe to or send the payload to.\n\n`period` [*number*] - The period of validity for the subscription (in seconds)\n\n`name` [*string*] - The name to use for the subscribing device.\n\n`token` [*string*] - The token of the subscribing device.", "1-2": "Unsubscribes a device to a channel so the device will not receive push notifications.\n\nThis function has the following parameters:\n\n`platform` [*string*] - The name of the push platform.\n\n`channel` [*string*] - The channel to subscribe to or send the payload to.\n\n`token` [*string*] - The token of the subscribing device.", "2-2": "Sends a push notification to all devices subscribed to the channel.\n\nThis function has the following parameters:\n\n`channel` [*string*] - The channel to send push notifications. All devices subscribed to this channel will receive the push notification.\n\n`payload` [*object*] - The payload to send to devices." }, "cols": 3, "rows": 3 } [/block] <div id="remote-endpoint-request-object-cryptographic-keys"></div> ## Cryptographic Key ### Cryptographic Key Request Remote endpoint request objects of type `Cryptographic key` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "generate(keytype, bits, privateKeyName, publicKeyname )", "0-1": "`function`", "0-2": "Generates a public/private key pair. \n\nThis function has the following parameters:\n\n`keytype` [*string*] - Value indicating the cryptosystem type (“ecdsa”, default “rsa”). \n \n`bits` [*integer*] - Bit length of modulus (should be even, exclude for ECDSA).\n \n`privateKeyName` [*string*] - Name of the private key added to the keystore.\n \n`publicKeyName` [*string*] - Name of the public key added to the keystore.", "1-0": "create(contents, name, password, pkcs12)", "2-0": "destroy(name)", "1-1": "`function`", "2-1": "`function`", "1-2": "Create a new key in the keystore with contents provided.\n\nThis function has the following parameters:\n\n`contents` [*string*] - The base64 encoded key string. \n \n`name` [*string*] - Name of the private or public key created in the keystore.\n \n`password` [*string*] - Private key password if necessary.\n \n`pkcs12` [*boolean*] - Indicates if certificate is of pkcs12 format.", "2-2": "Delete a key from keystone:\n\n`name` [*string*] - Name of the key to be deleted from the keystore." }, "cols": 3, "rows": 3 } [/block] ### Cryptographic Key Response Remote endpoint response objects of type `Cryptographic Key` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "statusCode", "0-1": "`number`", "1-0": "body", "1-1": "`object`", "2-0": "error", "2-1": "`string`", "0-2": "The status code of the requested operation.", "1-2": "Outgoing response body.", "2-2": "Error string returned from the request." }, "cols": 3, "rows": 3 } [/block] ### Cryptographic Key Request/Response Examples [block:code] { "codes": [ { "code": "key.request = new AP.Key.Request();\nvar options = {\n privateKeyName: \"priv\", \n publicKeyName: \"pub\" }; //default 2048 RSA keys\nkey.request.generate(options);", "language": "javascript", "name": "generate() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "// generate() RSA with different bit length\nkey.request = new AP.Key.Request();\nvar options = {\n privateKeyName: \"priv4096\", \n bits: 4096,\n publicKeyName: \"pub4096\" }; //4096 bit RSA key \nkey.request.generate(options);", "language": "javascript", "name": "generate() RSA key before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "// generate() ECDSA key, bits are not passed\nkey.request = new AP.Key.Request();\nvar options = {\n keytype: \"ecdsa\"\n privateKeyName: \"privateECDSA\", \n publicKeyName: \"publicECDSA\" };\nkey.request.generate(options);", "language": "javascript", "name": "generate() ECDSA key before request logic" } ] } [/block] generate() after request logic [block:code] { "codes": [ { "code": "key.request = new AP.Key.Request();\nkey.request.create({\n\tcontents: “BASE64_ENCODED_CONTENTS”, \n\tname: \"my_key\", \n\tpassword: “secret_if_necessary”, \n\tpkcs12: false\n});", "language": "javascript", "name": "created() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "key.request = new AP.Key.Request();\nkey.request.destroy({\n\tname: \"my_key\"\n});", "language": "javascript", "name": "delete() before request logic" } ] } [/block] [block:code] { "codes": [ { "code": "response = new AP.HTTP.Response();\nif(key.response.error) {\n\tresponse.statusCode = 422;\n\tresponse.body = key.response.error;\n} else response.body = \"success\";", "language": "javascript", "name": "after request logic" } ] } [/block] <div id="remote-endpoint-request-object-sap-hana"></div> ## SAP Hana ### SAP Hana Request Remote endpoint request objects of type `SAP Hana` have the following properties and methods: [block:parameters] { "data": { "h-0": "property", "h-1": "type", "h-2": "description", "0-0": "execute (stmt, params)", "0-1": "`function`", "1-1": "`function`", "1-0": "query (stmt, params, resultTypes)", "1-2": "The request's SQL statement to be executed. Must be a query that does not modify data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's statement to be executed.\n\n`params` [*array*] - The request's parameters passed to SAP Hana.\n\n`resultTypes` [*object*] - The result types expected by the query. The keys represent the column names of the result set, and the values represent a conversion object such as Int or Float.", "0-2": "The request's SQL statement to be executed. Must be an update that modifies data.\n\nThis function has the following parameters:\n\n`stmt` [*string*] - The request's statement to be executed.\n\n`params` [*array*] - The request's parameters passed to SAP Hana." }, "cols": 3, "rows": 2 } [/block] # Nanoscale.io Helper Functions and Objects ## Session Object Session is a hash that is initialized and loaded by nanoscale.io server based on the cookie or server-side session. The developer can use the following functions to write, read and delete session variables: - **session.set()** - **session.get()** - **session.delete()** Use isSet() to check if the a session variable exists. [block:code] { "codes": [ { "code": "// Check if session variable \"token\" is set\nsession.isSet(\"token\");\n \n// Set session variable \"token\" to value \"abcde\"\nsession.set(\"token\", \"abcde\");\n \n// Log session variable \"token\" using get function\nlog(session.get(\"token\"));\n \n// Delete session variable \"token\"\nsession.delete(\"token\");", "language": "javascript", "name": "Example calls on “token” session variables" } ] } [/block] ## Env Hash Env is a hash that is loaded based on environment set on Proxy Endpoint. [block:code] { "codes": [ { "code": "// Set the Authorization header for Proxy Request using a variable named \"my_auth\"\nrequest.header.Authorization = env.my_auth;", "language": "javascript", "name": "Sample code for Env Hash" } ] } [/block] ## Log Function The Log function can be used to write information to the nanoscale.io log. [block:code] { "codes": [ { "code": "// Log \"hello\"\nlog(“hello”);", "language": "javascript", "name": "Sample code for Log Function" } ] } [/block] ## JSON/XML Conversion Function Convert data from JSON to XML and vice versa. [block:code] { "codes": [ { "code": "//convert JSON to XML\nvar jsonToConvert = JSON.parse(request.body);\nvar xml = AP.Conversion.toXML(jsonToConvert);\nresponse.body = xml;\n\nAP.Conversion.JSONPath\n\n\n//convert XML to JSON\nvar xmlToConvert = request.body;\nvar json = AP.Conversion.toJson(xmlToConvert);\nresponse.headers['Content-Type'] = 'application/json';\nresponse.body = json;\n\nAP.Conversion.XMLPath", "language": "javascript" } ] } [/block] ## Encrypt and Decrypt Function Different options for encryption and decryption of data using the keys in the keystore [block:code] { "codes": [ { "code": "//encrypt using a key in the nanoscale.io keystore called 'public'\nresponse.body = AP.Crypto.encrypt(request.body, {key: \"public\" });\n\n//decrypt using a key in the nanoscale.io keystore called 'private' with sha256 algorithm has function\nresponse.body = AP.Crypto.decrypt(request.body, {key: \"private\", algorithm: \"sha256\"});\n\n//supported algorithms are:\n//AP.Crypto.HashingAlgorithms = {\n// md5: \"md5\",\n// sha1: \"sha1\",\n// sha256: \"sha256\",\n// sha512: \"sha512\",\n// sha384: \"sha384\",\n// sha512_256: \"sha512_256\",\n// sha3_224: \"sha3_224\",\n// sha3_256: \"sha3_256\",\n// sha3_384: \"sha3_384\",\n// sha3_512: \"sha3_512\",\n//}\n\n\n//encrypt using AES encryption algorithm\nvar plaintext = \"let's encrypt this.\";\nvar key = \"YWFhYWFhYWFhYWFhYWFhYQ==\";\nvar iv = \"YWFhYWJiYmJjY2NjZGRkZA==\";\n\n//IV is optional, if you do not supply one to the encryption function a suitable \n//one is generated. IV is not necessary during decryption since it's the first 16\n//bytes of the payload.\nvar encrypted = AP.Crypto.Aes.encrypt(plaintext, { key: key, iv: iv }); \n\nvar decrypted = AP.Crypto.Aes.decrypt(encrypted, { key: key });\n\nresponse = new AP.HTTP.Response();\nresponse.setJSONBodyPretty({\n plaintext: plaintext,\n encrypted: String(encrypted),\n decrypted: String(decrypted)\n})", "language": "javascript" } ] } [/block] ## Encoding Function Convert data to and from Base64 and Hex [block:code] { "codes": [ { "code": "//Convert data to Base64\n//passing in 'convert to base64'\nvar valueToEncode = request.params.encode;\nvar encoded = AP.Encoding.toBase64(valueToEncode);\n//encodes to 'Y29udmVydCB0byBiYXNlNjQ='\nresponse.body = encoded;\n\n//Convert data from Base64\n//passing in 'Y29udmVydCB0byBiYXNlNjQ='\nvar valueToDecode = request.params.decode;\nvar decoded = AP.Encoding.fromBase64(valueToDecode);\n//decodes to 'convert to base64'\nresponse.body = decoded;\n\n//Convert data to Hex\n//passing in 'convert to hex' as param\nvar valueToHex = request.params.hexit;\nvar hexed = AP.Encoding.toHex(valueToHex);\n//converts to '636f6e7665727420746f20686578'\nresponse.body = hexed;\n\n//Convert data from Hex\n//passing in '636f6e7665727420746f20686578'\nvar valueFrmHex = request.params.xeh;\nvar value = AP.Encoding.fromHex(valueFrmHex);\n//converts to 'conver to hex'\nresponse.body = value;", "language": "javascript" } ] } [/block] # Nanoscale.io JS Object Access and Availability [block:callout] { "type": "info", "body": "To learn more, please refer to the [Request/Response Lifecycle](doc:request-response-lifecycle) section or view the sample API Proxy Endpoint called “**Request and response lifecycle**” that you imported in the Quick Start Guide." } [/block] The following images represent objects and functions, which are available or can be added during the specific steps within the workflow: ## Logic Component Workflow [block:image] { "images": [ { "image": [ "https://files.readme.io/WfmXNplgStCjFUFXXcku_user-guide-javascript-object-reference-logic-component-workflow.png", "user-guide-javascript-object-reference-logic-component-workflow.png", "1228", "587", "#6192c7", "" ] } ] } [/block] ## Single Call Component Workflow [block:image] { "images": [ { "image": [ "https://files.readme.io/6w89VE0S5adAahVkNCuq_user-guide-javascript-object-reference-single-call-component-workflow.png", "user-guide-javascript-object-reference-single-call-component-workflow.png", "2000", "1082", "#6093c8", "" ] } ] } [/block] *Assume code name is myEndpoint in the above diagram For developer's convenience, the editor in the JavaScript logic blocks supports auto-completion: 1. **“Gateway”** - These are nanoscale.io Objects and Properties 2. **“keyword”** - These are Standard JavaScript Objects and Underscore.js library Objects [block:image] { "images": [ { "image": [ "https://files.readme.io/HVcLZj4DRhqWl5AR4UcI_user-guide-javascript-object-reference-auto-complete.png", "user-guide-javascript-object-reference-auto-complete.png", "1280", "176", "#ededed", "" ] } ] } [/block] [block:callout] { "type": "info", "body": "Shared Libraries function and variables are not available in auto-complete list, since they are loaded at run-time." } [/block]