Sometimes (or in some cases, every time) when you invoke a custom API Service, you may need additional information about the context from which the HTTP request was sent/received, such as user or device information. To collect that information, we provide a class called InvocationContext.
This class has a number of convenient methods to determine various request parameters. Until recently, there were six such parameters:
InvocationContext.getDeviceType(); InvocationContext.getAppId(); InvocationContext.getUserId(); InvocationContext.getUserRoles(); InvocationContext.getUserToken(); InvocationContext.getHttpHeaders();
Only the last one is related to the http request itself – getHttpHeaders.
Recently we added three more methods:
InvocationContext.getHttpPath(); InvocationContext.getHttpPathParams(); InvocationContext.getHttpQueryParams();
Let’s see what we can do with them now.
First, we need to download CodeRunner and create an API Service.
1) Download
2) Create service
For our example, let’s collect statistics about the geographical location of the visitors/users of our service. We’ll also add the ability to use an optional additional parameter to change the behavior of the service.
The code (please pay attention to the bold text):
import com.backendless.Backendless; import com.backendless.BackendlessUser; import com.backendless.commons.DeviceType; import com.backendless.servercode.BackendlessService; import com.backendless.servercode.InvocationContext; import java.util.HashMap; import java.util.Map; @BackendlessService public class MyServiceWithLogging { public String returnInfo( String tag ) { // use query parameter to switch method in 'test' mode String test = InvocationContext.getHttpQueryParams().get( "test" ); if( test != null || Boolean.valueOf( test ) ) { System.out.println( "This is a test request, so we do nothing, except logging." ); // collect and print data about request logRequestInfo(); return "test request"; } // use query parameter to perform special actions according to special key String subscriptionKeyFromRequest = InvocationContext.getHttpQueryParams().get( "special-subscription-key" ); if (subscriptionKeyFromRequest != null) { BackendlessUser user = Backendless.Data.of( BackendlessUser.class ).findById( InvocationContext.getUserId() ); String subscriptionKey = (String) user.getProperty( "special-subscription-key" ); if (subscriptionKeyFromRequest.equals( subscriptionKey )) { // do some special stuff return "special subscription"; } } // your ordinary business logic here return "Here it is."; } private void logRequestInfo() { DeviceType deviceType = InvocationContext.getDeviceType(); System.out.println( deviceType ); Map<String, String> headers = InvocationContext.getHttpHeaders(); System.out.println( headers ); // here you can log the remote users address String[] remoteAddress = headers.get( "Remote-Address" ).split( ":" ); Map<String, Object> remoteAddressRecord = new HashMap<>(); remoteAddressRecord.put( "host", remoteAddress[0] ); remoteAddressRecord.put( "port", Integer.parseInt( remoteAddress[1] ) ); remoteAddressRecord.put( "userId", InvocationContext.getUserId() ); Backendless.Data.of( "remote_addresses" ).save( remoteAddressRecord ); // new feature String path = InvocationContext.getHttpPath(); System.out.println( path ); // new feature Map<String, String> pathParams = InvocationContext.getHttpPathParams(); System.out.println( pathParams ); // new feature Map<String, String> queryParams = InvocationContext.getHttpQueryParams(); System.out.println( queryParams ); System.out.println(); } }
The last step is to build the project and deploy the code, using ./bin/CodeRunner.sh.
That’s all there is to it. Thanks for reading, and happy coding!