Package com.veeva.vault.sdk.api.webapi
Web APIs
A Web API entrypoint is a Java class that implements theWebApi 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();
}
}
-
ClassDescriptionInvoked to service a POST request; takes
WebApiContextas input.Input to aWebApi.Provides methods to set errors for aWebApiResponse.Creates an instance ofWebApiError.Provides methods to retrieve file data for aWebApiResponse.Creates an instance ofWebApiFileResponseData.Indicates a class is aWebApi.Represents a file reference included in a multipart request body of aWebApi.Represents a multipart request body for aWebApi.Types of data available for request body direct conversion support.Includes methods to retrieve WebAPIRequest data.Represents aWebApiRequestexecution response.Creates an instance ofWebApiResponse.SetsWebApiErrors for aWebApiResponse.Contains valid values to define the status of aWebApiRequest.