Creating a Request

Send a data request to the backend through the SAP Mobile Platform Server asynchronously or synchronously. If there is no network connectivity, Request library requests are queued in a persistent database, and invoked when the network becomes available. Use the Request library to develop applications with direct connectivity to Gateway, or to register users in the Management Cockpit.

Creating an Asynchronous Request

The SAP-recommended approach for creating a request is to send the data request to the backend through the SAP Mobile Platform Server asynchronously.

  1. To enable offline capability, it is mandatory to set the response listeners using the following code, before invoking the request. Once the offline listeners are set, responses are notified to these listeners bypassing the online listeners set on each request for change requests (PUT, POST, DELETE). For GET requests, responses are notified to the corresponding listeners set on the Request object. The implementation of these listeners is seamless for both online or offline scenarios.
    /*Set the delegate to receive the response */
    [RequestBuilder setDelegate:self];
    /*Set the success listener */
    [RequestBuilder setDidFinishSelector:@selector(reqSuccess:)];
    /*Set the failure listener */
    [RequestBuilder setDidFailSelector:@selector(reqFail:)];
    

    Since all the responses to change requests are notified to these listeners, it is required to co-relate the response received with the request sent. A member property requestTag is provided in the Request object. The requestTag can be set while invoking the request and can be read while reading the response in these listeners.

  2. To create the request asynchronously for both online and offline capability, use the following code:
    [RequestBuilder setRequestType:HTTPRequestType];
    /*Enable XCSRF handling for OData requests*/
    [RequestBuilder enableXCSRF:YES];
    /*Initialize the Requesting class with the endpoint URL after successful registration */
    id<Requesting> serviceDocRequest = [RequestBuilder requestWithURL:[[NSURL alloc] initWithString:applicationEndpoint]];
    /*Set user name */
    [serviceDocRequest setUsername:self.username.text];
    /*Set password */
    [serviceDocRequest setPassword:self.password.text];
    /*Set the required request headers*/
    [serviceDocRequest setRequestMethod:@"GET"];
    [serviceDocRequest addRequestHeader:@"X-Requested-With" value:@"XmlHttpRequest"];
    [serviceDocRequest addRequestHeader:@"Content-Type" value:@"application/xml; charset=UTF-8"];
    [serviceDocRequest addRequestHeader:@"Accept" value:@"application/xml,application/atom+xml"];
    /*If the request is an online request, it is mandatory to register the following listeners. In case of an offline listeners, these listeners will be overridden by the listeners in Step 1.
    /*Set the delegate to receive the response */
    [serviceDocRequest setDelegate:self];
    /*Set the success listener */
    [serviceDocRequest setDidFinishSelector:@selector(didFinishRequest:)];
    /*Set the failure listener */
    [serviceDocRequest setDidFailSelector:@selector(didFailRequest:)];
    serviceDocRequest.requestTag = 1; // Useful for a change request.
    /*Invoke the startAsyncronous API to send the request from client to server asynchronously */
    [serviceDocRequest startAsynchronous];
    

Automatic Delta Query Handling

The Request object is enabled to handle delta queries by default. In an offline mode (when the cache is used), the Request object picks up the delta link for the specified URL from the cache and calls it. The delta link queries for resources that have been created, modified, or deleted, after the previous request was made (which generated this delta link). You can stop this behavior by:
  • Not including the Cache library in the project, so that the Request library does not link to the cache and persistence, and does not find a corresponding delta link. The original URL is called as before.
  • Setting the disableDeltaHandling property explicitly on the Request object using the code:
    serviceDocRequest.disableDeltaHandling = YES;
    

Creating a Batch Request

Batch processing allows you to send multiple requests in a single batch request to the Gateway.  The batch request is a multipart POST request that contains one or more changesets comprising other POST, PUT, or DELETE requests.  The batch request can also contain GET-based retrieval requests. The Gateway processes the batch request, and the responses to the various requests that make up the batch request are combined into a single response and sent back to the user as a single response.

  1. Initialize the batch request:
    BatchRequest *batchRequest = [[BatchRequest alloc] initWithURL:[[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/$batch",applicationEndpoint]]];
    
  2. Add a retrieve request to the batch request:
    Id<requesting> request1;
    request1 = [RequestBuilder requestWithURL:[NSURL URLWithString:@"TravelagencyCollection"]];
    [request1 setRequestMethod:@"GET"];
    [batRequest addRetrieveRequestToBatch:request1 withError:&error];
    
  3. Add changesets to the batch request:
    [RequestBuilder enableXCSRF:YES];
    BatchRequest *batchRequest = [[BatchRequest alloc] initWithURL:[NSString stringWithFormat:@"%@/$batch",ApplicationEndPoint];
    Id<SDMRequesting> postRequest = [RequestBuilder requestWithURL:[NSURL URLWithString:@"TravelagencyCollection"]];
    [postRequest setRequestMethod:@"POST"];
    [postRequest addRequestHeader:@"Content-Type" value:@"application/atom+xml"];
    [postRequest addRequestHeader:@"Content-Length" value:@"1005"];
    
     NSMutableData* postData;
        ///GetEntry is an ODataObject which has the response for GET done on single entry from a collection
            ODataEntry const *postBody = [[ODataEntry alloc]initWithEntitySchema:Getentry.getEntitySchema];  
            [postBody.fields setValuesForKeysWithDictionary:Getentry.fields];
            
            ODataPropertyValueObject* filterValue = [postBody getPropertyValueByPath:@"agencynum"];  ///agencynum is the primary key or the unique value
            
            filterValue.rawValue=@"00000127";
    
            ODataPropertyValueObject* filterValue = [postBody getPropertyValueByPath:@"agencyname"];  
            
            filterValue.rawValue=@"BestAgency";
        
            //The following code builds an atom post body:
            ODataEntryBody *entryBody = buildODataEntryRequestBody(postBody, ENTRY_OPERATION_CREATE, serviceDocument, NO, BUILD_STYLE_ATOM_XML);  
        
        //The following code can be used to build a JSON post body:
         //  ODataEntryBody *entryBody = buildODataEntryRequestBody(postBody, ENTRY_OPERATION_CREATE, serviceDocument, NO, BUILD_STYLE_JSON);
    
             postData = [[entryBody.body dataUsingEncoding:NSUTF8StringEncoding]mutableCopy];
             [self.request setPostBody:postData];    
    [batchRequest addRequestToChangeset:postRequest withError:&error];
    
    /* Ensure the POST URL is relative to the batch URL */
    
  4. Invoke the batch request either synchronously or asynchronously:
    /* Example for Asynchronous request */
    [batchRequest setUsername:self.username.text];
    [batchRequest setPassword:self.password.text];
    /*Set the delegate to receive the response */
    [batchRequest setDelegate:self];
    /*Set the success listener */
    [batchRequest setDidFinishSelector:@selector(didFinishRequest:)];
    /*Set the failure listener */
    [batchRequest setDidFailSelector:@selector(didFailRequest:)];
    /*Invoke the startAsyncronous API to send the request from client to server asynchronously */
    [batchRequest startAsynchronous];