From 1982b6d74987d784f742430bae61495c196527a0 Mon Sep 17 00:00:00 2001 From: Brian Bell Date: Mon, 8 Jun 2015 07:40:30 -0400 Subject: [PATCH] Add support for returning service-specific response headers from a list service request --- .gitignore | 4 ++ .../restfulapi/RestfulApiController.groovy | 5 ++ .../restfulapi/PagedResultArrayList.groovy | 8 +++- .../RestfulApiControllerSpec.groovy | 47 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ba2e586..b615a6f 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ plugin.xml *en_PS.properties test/test-restful-api/web-app/css/**-rtl.css /plugin.xml +/.settings +/target-eclipse +/.classpath +/.project diff --git a/grails-app/controllers/net/hedtech/restfulapi/RestfulApiController.groovy b/grails-app/controllers/net/hedtech/restfulapi/RestfulApiController.groovy index 1cd166d..33e866c 100644 --- a/grails-app/controllers/net/hedtech/restfulapi/RestfulApiController.groovy +++ b/grails-app/controllers/net/hedtech/restfulapi/RestfulApiController.groovy @@ -238,6 +238,11 @@ class RestfulApiController { holder.addHeader(totalCountHeader, count) holder.addHeader(pageOffsetHeader, requestParams.offset ? requestParams?.offset : 0) holder.addHeader(pageMaxHeader, requestParams.max ? requestParams?.max : result.size()) + if (result.hasProperty("httpResponseHeaders") && result.httpResponseHeaders instanceof Map) { + result.httpResponseHeaders.each { + if (it.value != null) holder.addHeader(it.key, it.value.toString()) + } + } renderSuccessResponse( holder, 'default.rest.list.message' ) } } diff --git a/src/groovy/net/hedtech/restfulapi/PagedResultArrayList.groovy b/src/groovy/net/hedtech/restfulapi/PagedResultArrayList.groovy index e8bfd95..7d8ccdf 100644 --- a/src/groovy/net/hedtech/restfulapi/PagedResultArrayList.groovy +++ b/src/groovy/net/hedtech/restfulapi/PagedResultArrayList.groovy @@ -22,13 +22,19 @@ package net.hedtech.restfulapi class PagedResultArrayList extends ArrayList implements PagedResultList { private long totalCount + private Map httpResponseHeaders - PagedResultArrayList(Collection c, long totalCount) { + PagedResultArrayList(Collection c, long totalCount, Map httpResponseHeaders = null) { super(c) this.totalCount = totalCount + this.httpResponseHeaders = httpResponseHeaders } long getTotalCount() { totalCount } + + Map getHttpResponseHeaders() { + httpResponseHeaders + } } diff --git a/test/test-restful-api/test/unit/net/hedtech/restfulapi/RestfulApiControllerSpec.groovy b/test/test-restful-api/test/unit/net/hedtech/restfulapi/RestfulApiControllerSpec.groovy index 189b0f6..0943f54 100644 --- a/test/test-restful-api/test/unit/net/hedtech/restfulapi/RestfulApiControllerSpec.groovy +++ b/test/test-restful-api/test/unit/net/hedtech/restfulapi/RestfulApiControllerSpec.groovy @@ -1883,6 +1883,53 @@ class RestfulApiControllerSpec extends Specification { 200 == response.status '2' == response.getHeaderValue( 'X-hedtech-totalCount' ) } + + def "Test HTTP Response Headers"() { + setup: + //use default extractor for any methods with a request body + config.restfulApiConfig = { + resource 'things' config { + representation { + mediaTypes = ['application/json'] + extractor = new DefaultJSONExtractor() + } + } + } + controller.init() + + //mock the appropriate service method, expect exactly 1 invocation + def mock = Mock(ThingService) + mock.list(_) >> {return new PagedResultArrayList([[name:'foo']], 5, + ["X-hedtech-responseHeader1":"value-1", + "X-hedtech-responseHeader2":42, // used to verify number converted to string + "X-hedtech-responseHeader3":null, // used to verify null valie is omitted + "X-hedtech-responseHeader4":"value-4"])} + controller.metaClass.getService = {-> mock} + + mockCacheHeaders() + + request.addHeader( 'Accept', 'application/json' ) + //incoming format always json, so no errors + request.addHeader( 'Content-Type', 'application/json' ) + params.pluralizedResourceName = 'things' + + when: + controller.list() + def json = JSON.parse response.text + + then: + 0*mock.count(_) >> {} + 200 == response.status + '5' == response.getHeaderValue( 'X-hedtech-totalCount' ) + 1 == json.size() + 'foo' == json[0].name + + // verify response headers + 'value-1' == response.getHeaderValue( 'X-hedtech-responseHeader1' ) + '42' == response.getHeaderValue( 'X-hedtech-responseHeader2' ) + null == response.getHeaderValue( 'X-hedtech-responseHeader3' ) + 'value-4' == response.getHeaderValue( 'X-hedtech-responseHeader4' ) + } private void mockCacheHeaders() {