/
Forms API
Got feedback or spotted a mistake?
Leave a comment at the end of this page or email contact@krishagni.com
Forms API
The following example program demonstrates forms API by
- retrieving form metadata
- saving form data
- retrieving record ID of form data
- retrieving form data
- updating form data
- deleting the form data
The program is written using Java and Spring REST framework. OpenSpecimen integration developers are free to choose language and tools of their choice.
public class TestFormApis { // // this can be a configuration setting. For illustration purpose, API base URL is hardcoded // private static final String API_BASE_URL = "http://myopenspecimenserver.com/openspecimen/rest/ng"; private static RestTemplate template = new RestTemplate(); // // Input specimen ID and this program will add destruction date and remove it. // public static void main(String[] args) throws Exception { if (args.length == 0) { return; } // // Step 0: Input specimen ID could come from any source. // In this example, specimen ID is picked from command line arguments // Long specimenId = Long.parseLong(args[0]); // // Step 1: Login and get an authentication token for use in subsequent API calls // String token = login(); // // Step 2: Retrieve form metadata // Map<String, Object> formMetadata = getFormMetadata(token, "Specimen", specimenId, "Specimen Destruction Details"); if (formMetadata == null) { // No form with name "Specimen Destruction Details" attached at Specimen level return; } // // Step 3: Save form data // Long recordId = saveFormData(token, specimenId, formMetadata); System.out.println("Successfully saved form record: " + recordId); // // recordId can be used to maintain a mapping between your data and OpenSpecimen form record // this mapping can be subsequently used for updating form record without resorting to step 4. // // // Step 4: Retrieve form record ID // recordId = getRecordId(token, "Specimen", specimenId, formMetadata); // // Step 5: Retrieve form data // Map<String, Object> formData = getFormData(token, recordId, formMetadata); System.out.println(formData.get("destructionDate")); // use the form data fields for processing System.out.println(formData.get("destructionMethod")); // // Step 6: Update form data // updateFormData(token, recordId, formData); // // Step 7: Delete form data // deleteFormData(token, recordId, formMetadata); // // Step 8: logout // logout(token); } private static String login() { // // username and password could be fetched from your client configuration database // Map<String, Object> payload = new HashMap<>(); payload.put("loginName", "admin@admin.com"); payload.put("password", "Login420"); Map<String, Object> resp = template.postForObject(getUrl("/sessions"), payload, Map.class); return (String) resp.get("token"); } private static void logout(String token) { invokeApi(HttpMethod.DELETE, "/sessions", token, null, Map.class); template.exchange(getUrl("/sessions"), HttpMethod.DELETE, getHttpEntity(token), Map.class); } private static Map<String, Object> getFormMetadata(String token, String entityType, Long objectId, String formName) throws Exception { String uri = null; if (entityType.equals("Specimen")) { uri = "/specimens/" + objectId + "/forms"; } else if (entityType.equals("Visit")) { uri = "/visits/" + objectId + "/forms"; } else if (entityType.equals("CollectionProtocolRegistration")) { uri = "/collection-protocol-registrations/" + objectId + "/forms"; } else { throw new IllegalArgumentException("Invalid entity type: " + entityType); } Map[] forms = invokeApi(HttpMethod.GET, uri, token, null, Map[].class); for (Map form : forms) { if (Objects.equals(form.get("formCaption"), formName)) { return form; } } return null; } private static Long saveFormData(String token, Long specimenId, Map<String, Object> formMetadata) { Map<String, Object> appData = new HashMap<>(); appData.put("useUdn", true); // to let API know we use human readable field names instead of cryptic ones appData.put("formCtxtId", formMetadata.get("formCtxtId")); appData.put("objectId", specimenId); Calendar cal = Calendar.getInstance(); cal.set(2020, 12, 31); long destructionDate = cal.getTimeInMillis(); Map<String, Object> formData = new HashMap<>(); formData.put("appData", appData); // // form field values // formData.put("destructionDate", destructionDate); formData.put("destructionMethod", "Cremation"); Number formId = (Number)formMetadata.get("formId"); String uri = "/forms/" + formId + "/data"; Map savedData = invokeApi(HttpMethod.POST, uri, token, formData, Map.class); // // return record ID on saving form data // return ((Number)savedData.get("id")).longValue(); } private static Long updateFormData(String token, Long recordId, Map<String, Object> formData) { formData.put("recordId", recordId); formData.put("destructionMethod", "Not Specified"); Number formId = (Long)formData.get("containerId"); String uri = "/forms/" + formId + "/data/" + recordId; Map savedData = invokeApi(HttpMethod.PUT, uri, token, formData, Map.class); return ((Number)savedData.get("id")).longValue(); } private static Long getRecordId(String token, String entityType, Long objectId, Map<String, Object> formMetadata) { String uri = ""; if (entityType.equals("Specimen")) { uri = "/specimens/"; } else if (entityType.equals("Visit")) { uri = "/visits/"; } else if (entityType.equals("CollectionProtocolRegistration")) { uri = "/collection-protocol-registrations/"; } else { throw new IllegalArgumentException("Invalid entity type: " + entityType); } Long formCtxtId = (Long) formMetadata.get("formCtxtId"); uri = String.format(uri + "%d/forms/%d/records", objectId, formCtxtId); Map<String, Object> entityRecs = invokeApi(HttpMethod.GET, uri, token, null, Map.class); Map<String, Object>[] records = (Map<String, Object>[])entityRecs.get("records"); if (records == null || records.length == 0) { return null; } return (Long)records[0].get("recordId"); } private static Map<String, Object> getFormData(String token, Long recordId, Map<String, Object> formMetadata) { Number formId = (Number)formMetadata.get("formId"); String uri = "/forms/" + formId + "/data/" + recordId; return (Map<String, Object>)invokeApi(HttpMethod.GET, uri, token, null, Map.class); } private static void deleteFormData(String token, Long recordId, Map<String, Object> formMetadata) { Number formId = (Number)formMetadata.get("formId"); String uri = "/forms/" + formId + "/data/" + recordId; invokeApi(HttpMethod.DELETE, uri, token, null, Long.class); } private static <T> T invokeApi(HttpMethod httpMethod, String uri, String token, Object body, Class<T> returnType) { ResponseEntity<T> resp = template.exchange(getUrl(uri), httpMethod, getHttpEntity(token, body), returnType); if (resp.getStatusCode() == HttpStatus.OK) { return resp.getBody(); } // // Handle API failures // throw new RuntimeException("Error invoking API: " + uri); } private static HttpEntity<?> getHttpEntity(String token) { return getHttpEntity(token, null); } private static HttpEntity<?> getHttpEntity(String token, Object body) { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.set("X-OS-API-TOKEN", token); // API auth token header return new HttpEntity<>(body, headers); } private static String getUrl(String uri) { return API_BASE_URL + uri; } }
, multiple selections available,
Related content
Update Specimen
Update Specimen
Read with this
Bulk Import via API
Bulk Import via API
Read with this
REST APIs
REST APIs
Read with this
Form Attachment Details
Form Attachment Details
Read with this
Create User
Create User
Read with this
OpenSpecimen Support
OpenSpecimen Support
Read with this
Got feedback or spotted a mistake?
Leave a comment at the end of this page or email contact@krishagni.com