Skip to content

Commit

Permalink
Merge pull request #40 from AtlasOfLivingAustralia/39-extend-webservi…
Browse files Browse the repository at this point in the history
…ce-post

#39 change webService body params to Object
  • Loading branch information
adam-collins authored Feb 8, 2024
2 parents 4049e0e + 2382fca commit e2ebdcc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ class WebService {
* The body map will be sent as the JSON body of the request (i.e. use request.getJSON() on the receiving end).
*
* @param url The url-encoded url to send the request to
* @param body Map containing the data to be sent as the post body
* @param body Object containing the data to be sent as the post body. e.g. Map, Array
* @param params Map of parameters to be appended to the query string. Parameters will be URL-encoded automatically.
* @param contentType the desired content type for the request. Defaults to application/json
* @param includeApiKey true to include the service's API Key in the request headers (uses property 'service.apiKey'). If using JWTs, instead sends a JWT Bearer tokens Default = true.
* @param includeUser true to include the userId and email in the request headers and the ALA-Auth cookie. If using JWTs sends the current user's access token, if false only sends a ClientCredentials grant token for this apps client id Default = true.
* @param customHeaders Map of [headerName:value] for any extra HTTP headers to be sent with the request. Default = [:].
* @return [statusCode: int, resp: [:]] on success, or [statusCode: int, error: string] on error
*/
Map put(String url, Map body, Map params = [:], ContentType contentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
Map put(String url, Object body, Map params = [:], ContentType contentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
send(PUT, url, params, contentType, body, null, includeApiKey, includeUser, customHeaders)
}

Expand All @@ -100,15 +100,15 @@ class WebService {
* The body map will be sent as the body of the request (i.e. use request.getJSON() on the receiving end).
*
* @param url The url-encoded url to send the request to
* @param body Map containing the data to be sent as the post body
* @param body Object containing the data to be sent as the post body. e.g. Map, Array
* @param params Map of parameters to be appended to the query string. Parameters will be URL-encoded automatically.
* @param contentType the desired content type for the request. Defaults to application/json
* @param includeApiKey true to include the service's API Key in the request headers (uses property 'service.apiKey'). If using JWTs, instead sends a JWT Bearer tokens Default = true.
* @param includeUser true to include the userId and email in the request headers and the ALA-Auth cookie. If using JWTs sends the current user's access token, if false only sends a ClientCredentials grant token for this apps client id Default = true.
* @param customHeaders Map of [headerName:value] for any extra HTTP headers to be sent with the request. Default = [:].
* @return [statusCode: int, resp: [:]] on success, or [statusCode: int, error: string] on error
*/
Map post(String url, Map body, Map params = [:], ContentType contentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
Map post(String url, Object body, Map params = [:], ContentType contentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
send(POST, url, params, contentType, body, null, includeApiKey, includeUser, customHeaders)
}

Expand All @@ -131,7 +131,7 @@ class WebService {
* </ul>
*
* @param url The url-encoded url to send the request to
* @param body Map containing the data to be sent as the post body
* @param body Object containing the data to be sent as the post body. e.g. Map, Array
* @param params Map of parameters to be appended to the query string. Parameters will be URL-encoded automatically.
* @param files List of 0 or more files to be included in the multipart request (note: if files is null, then the request will NOT be multipart)
* @param partContentType the desired content type for the request PARTS (the request itself will always be sent as multipart/form-data). Defaults to application/json. All non-file parts will have the same content type.
Expand All @@ -140,7 +140,7 @@ class WebService {
* @param customHeaders Map of [headerName:value] for any extra HTTP headers to be sent with the request. Default = [:].
* @return [statusCode: int, resp: [:]] on success, or [statusCode: int, error: string] on error
*/
Map postMultipart(String url, Map body, Map params = [:], List files = [], ContentType partContentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
Map postMultipart(String url, Object body, Map params = [:], List files = [], ContentType partContentType = ContentType.APPLICATION_JSON, boolean includeApiKey = true, boolean includeUser = true, Map customHeaders = [:]) {
send(POST, url, params, partContentType, body, files, includeApiKey, includeUser, customHeaders)
}

Expand Down Expand Up @@ -267,7 +267,7 @@ class WebService {
}

private Map send(Method method, String url, Map params = [:], ContentType contentType = ContentType.APPLICATION_JSON,
Map body = null, List files = null, boolean includeApiKey = true, boolean includeUser = true,
Object body = null, List files = null, boolean includeApiKey = true, boolean includeUser = true,
Map customHeaders = [:]) {
log.debug("${method} request to ${url}")

Expand All @@ -280,7 +280,7 @@ class WebService {

http.request(method, contentType) { request ->
configureRequestTimeouts(request)
configureRequestHeaders(headers, includeApiKey, includeUser, customHeaders)
configureRequestHeaders(delegate.headers, includeApiKey, includeUser, customHeaders)

if (files != null) {
// NOTE: order is important - Content-Type MUST be set BEFORE the body
Expand Down Expand Up @@ -390,13 +390,18 @@ class WebService {
}
}

private static HttpEntity constructMultiPartEntity(Map parts, List files, ContentType partContentType = ContentType.APPLICATION_JSON) {
private static HttpEntity constructMultiPartEntity(Object parts, List files, ContentType partContentType = ContentType.APPLICATION_JSON) {
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create()
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)

parts?.each { key, value ->
def val = partContentType == ContentType.APPLICATION_JSON && !(value instanceof net.sf.json.JSON) ? value as JSON : value
entityBuilder.addPart(key?.toString(), new StringBody((val) as String, partContentType))
if (parts instanceof Map) {
parts?.each { key, value ->
def val = partContentType == ContentType.APPLICATION_JSON && !(value instanceof net.sf.json.JSON) ? value as JSON : value
entityBuilder.addPart(key?.toString(), new StringBody((val) as String, partContentType))
}
} else {
def val = partContentType == ContentType.APPLICATION_JSON && !(parts instanceof net.sf.json.JSON) ? parts as JSON : parts
entityBuilder.addTextBody("json", val as String, partContentType)
}

files.eachWithIndex { it, index ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class WebServiceSpec extends Specification implements ServiceUnitTest<WebService
result.resp.query == 'a=%21&c=%26'
}

def "The request's content type should match the specified type - JSON"() {
def "The request's content type should match the specified type - JSON Map"() {
when:
Map result = service.post("${url}/post", [foo: "bar"], [:], ContentType.APPLICATION_JSON)

Expand All @@ -215,6 +215,24 @@ class WebServiceSpec extends Specification implements ServiceUnitTest<WebService
result.resp.bodyText == '{"foo":"bar"}'
}

def "The request's content type should match the specified type - JSON Array"() {
when:
Map result = service.post("${url}/post", ["foo", "bar"], [:], ContentType.APPLICATION_JSON)

then:
result.resp.contentType.toLowerCase() == ContentType.APPLICATION_JSON.toString()?.toLowerCase()
result.resp.bodyText == '["foo","bar"]'
}

def "The request's content type should match the specified type - Text"() {
when:
def result = new JsonSlurper().parseText(service.post("${url}/post", "String", [:], ContentType.TEXT_PLAIN)?.resp?.toString())

then:
result.contentType.toLowerCase() == ContentType.TEXT_PLAIN.toString()?.toLowerCase()
result.bodyText == 'String'
}

def "The request's content type should match the specified type - HTML"() {
when:
def result = new JsonSlurper().parseText(service.post("${url}/post", [foo: "bar"], [:], ContentType.TEXT_HTML)?.resp?.toString())
Expand Down Expand Up @@ -262,4 +280,4 @@ class WebServiceSpec extends Specification implements ServiceUnitTest<WebService
!result.error
result.resp.replaceAll("\\s", "") == '{"bar": "[c:d]", "data": null, "foo": "[a:b]", "files": ["file0", "file1"]}'.replaceAll("\\s", "")
}
}
}

0 comments on commit e2ebdcc

Please sign in to comment.