Package com.veeva.vault.sdk.api.webapi


package com.veeva.vault.sdk.api.webapi
This package provides interfaces to implement Web APIs.

Web APIs

A Web API entrypoint is a Java class that implements the WebApi interface and has the WebApiInfo annotation as shown below. Inside this class, you can apply logic to process API requests and return appropriate results.

The sample code below demonstrates how to define a Web API that can be called via POST once it is deployed. A POST call with URI https://{{vaultDNS}}/api/{version}/custom/hello_world will call the below Webapi's execute method.

In the WebApiInfo annotation, minimumVersion denotes the minimum API version that a caller can use to execute the Web API. In this example, if a caller provides a version lower than v24.3 in the request URI when the API is called, the request will fail. Each Web API must be assigned to a Web API Group, which Admins assign to permission sets. In the WebApiInfo annotation, apiGroup indicates the API group that is allowed to call the Web API. In this example, if the authenticated user calling this Web API does not have a permission set that grants access to the composite_apis__c API group, the request will fail.

 
 @WebApiInfo(endpointName="hello_world", minimumVersion = "v24.3", apiGroup = "composite_apis__c")
 @ExecuteAs(ExecuteAsUser.REQUEST_OWNER)
 public class HelloWorldWebApi implements WebApi {

     @Override
     public WebApiResponse execute(WebApiContext webApiContext) {
         JsonService jsonService = ServiceLocator.locate(JsonService.class);
         WebApiRequest webApiRequest = webApiContext.getWebApiRequest();
         WebApiResponse.Builder responseBuilder = webApiContext.newWebApiResponseBuilder();

         // Get request body as JsonObject
         JsonObject requestData = webApiRequest.getJsonObject();

         if(!requestData.contains("hello") || !requestData.contains("world")) {
             // Send failure response to caller
             JsonObject error = jsonService.newJsonObjectBuilder()
                     .setValue("error", "Expected request data not provided")
                     .build();
             return responseBuilder
                     .withData(error)
                     .withResponseStatus(WebApiResponseStatus.FAILURE)
                     .build();
         } else {
             // Send success response to caller, using provided request data
             String hello = requestData.getValue("hello", JsonValueType.STRING);
             String world = requestData.getValue("world", JsonValueType.STRING);
             JsonObject response = jsonService.newJsonObjectBuilder()
                     .setValue("helloworld", hello + world)
                     .build();
             return responseBuilder
                     .withData(response)
                     .withResponseStatus(WebApiResponseStatus.SUCCESS)
                     .build();
         }
     }
 }
 
 
The Web API above expects an application/json type request body, for example: { "hello": "foo", "world": "bar" }

Web APIs can also handle requests with multipart/form-data type request bodies, as shown in the Web API below.

 
 @WebApiInfo(endpointName="save_record_attachment", minimumVersion = "v24.3", apiGroup = "composite_apis__c")
 @ExecuteAs(ExecuteAsUser.REQUEST_OWNER)
 public class SaveRecordAttachmentWebApi implements WebApi {

     @Override
     public WebApiResponse execute(WebApiContext webApiContext) {
         RecordService recordService = ServiceLocator.locate(RecordService.class);
         LogService logService = ServiceLocator.locate(LogService.class);
         JsonService jsonService = ServiceLocator.locate(JsonService.class);

         // Get request body as multipart data
         WebApiMultipartRequestData multipartRequest = webApiContext.getWebApiRequest().getMultipartRequestData();
         String objectName = multipartRequest.getValue("objectName", WebApiMultipartValueType.STRING);
         String objectRecordId = multipartRequest.getValue("objectRecordId", WebApiMultipartValueType.STRING);
         String attachmentName = multipartRequest.getValue("attachmentName", WebApiMultipartValueType.STRING);
         WebApiMultipartFileReference fileReference = multipartRequest.getValue("fileReference", WebApiMultipartValueType.FILE);

         // Save record attachment using provided request data
         SaveRecordAttachment saveRecordAttachment = recordService.newSaveRecordAttachmentBuilder()
                 .withObjectName(objectName)
                 .withObjectRecordId(objectRecordId)
                 .withAttachmentName(attachmentName)
                 .withFileReference(fileReference)
                 .build();

         BatchSaveRecordAttachmentRequest batchSaveRecordAttachmentRequest = recordService.newBatchSaveRecordAttachmentRequestBuilder()
                 .withRecordAttachments(VaultCollections.asList(saveRecordAttachment))
                 .build();

         recordService.batchSaveRecordAttachments(batchSaveRecordAttachmentRequest)
             .onErrors(e -> {
                 for(RecordAttachmentBatchOperationError error : e) {
                     logService.error("Error: " + error.getError().getMessage());
                 }
             })
             .onSuccesses(s -> {
                 for(RecordAttachmentPositionResult result : s) {
                     logService.info("Attachment ID: " + result.getAttachmentId());
                 }
             }).execute();

         // Send success response to caller
         WebApiResponse.Builder responseBuilder = webApiContext.newWebApiResponseBuilder();
         return responseBuilder
                 .withData(jsonService.newJsonObjectBuilder().setValue("response", "Saved object record attachment").build())
                 .withResponseStatus(WebApiResponseStatus.SUCCESS)
                 .build();
     }
 }
 
 
Web APIs can also return file data to the caller by setting WebApiFileResponseData as their response data. The example below shows how to return record attachment file data.
 
 @WebApiInfo(endpointName = "get_record_attachment", minimumVersion = "v24.3", apiGroup = "composite_apis__c")
 @ExecuteAs(ExecuteAsUser.REQUEST_OWNER)
 public class GetRecordAttachmentWebApi implements WebApi {
     @Override
     public WebApiResponse execute(WebApiContext webApiContext) {
         RecordService recordService = ServiceLocator.locate(RecordService.class);
         ConnectionService connectionService = ServiceLocator.locate(ConnectionService.class);
         ExecuteAsService executeAsService = ServiceLocator.locate(ExecuteAsService.class);

         // Get request body as multipart data
         WebApiMultipartRequestData multipartRequest = webApiContext.getWebApiRequest().getMultipartRequestData();
         String objectName = multipartRequest.getValue("objectName", WebApiMultipartValueType.STRING);
         String objectRecordId = multipartRequest.getValue("objectRecordId", WebApiMultipartValueType.STRING);
         String attachmentId = multipartRequest.getValue("attachmentId", WebApiMultipartValueType.STRING);

         // Get record attachment FileReference using request parameters
         ConnectionContext localContext = executeAsService.executeAsJavaSdkUser(() -> {
             return connectionService.newLocalConnectionContext(RequestContextUserType.REQUEST_OWNER);
         });
         RecordAttachmentFileReferenceRequest attachmentRequest = recordService.newRecordAttachmentFileReferenceRequestBuilder()
                 .withConnectionContext(localContext)
                 .withObjectName(objectName)
                 .withObjectRecordId(objectRecordId)
                 .withAttachmentId(attachmentId)
                 .build();
         RecordAttachmentFileReference fileReference = recordService.newRecordAttachmentFileReference(attachmentRequest);

         // Return record attachment FileReference in API response
         WebApiFileResponseData fileResponseData = webApiContext.newWebApiFileResponseDataBuilder()
                 .withFileReference(fileReference)
                 .withFileName("attachment")
                 .build();
         return webApiContext.newWebApiResponseBuilder()
                 .withResponseStatus(WebApiResponseStatus.SUCCESS)
                 .withData(fileResponseData)
                 .build();
     }
 }