Skip to content

Commit

Permalink
Merge branch 'mainline' into feat/devcontainer
Browse files Browse the repository at this point in the history
  • Loading branch information
valter-silva-au authored Jan 23, 2024
2 parents 2b436f6 + 3338550 commit fd32e13
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ package {{package}}.handlers;
{{/apiInfo}}

import java.util.Map;
import java.util.List;

/**
* Represents an HTTP response from an api operation
Expand All @@ -460,6 +461,10 @@ public interface Response {
* Returns the response headers
*/
Map<String, String> getHeaders();
/**
* Returns the multi-value response headers
*/
Map<String, List<String>> getMultiValueHeaders();
}
###TSAPI_WRITE_FILE###
{
Expand All @@ -475,6 +480,7 @@ package {{package}}.handlers;
{{/apiInfo}}

import java.util.Map;
import java.util.List;

@lombok.experimental.SuperBuilder
@lombok.AllArgsConstructor
Expand All @@ -483,6 +489,7 @@ public class ApiResponse implements Response {
private String body;
private int statusCode;
private Map<String, String> headers;
private Map<String, List<String>> multiValueHeaders;
}
###TSAPI_WRITE_FILE###
{
Expand Down Expand Up @@ -639,6 +646,7 @@ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.List;

/**
* An "empty" chained request input used to warm up interceptors which extend the InterceptorWithWarmup
Expand All @@ -665,6 +673,11 @@ public class InterceptorWarmupChainedRequestInput<T> implements ChainedRequestIn
public Map<String, String> getHeaders() {
return new HashMap<>();
}

@Override
public Map<String, List<String>> getMultiValueHeaders() {
return new HashMap<>();
}
};
}
};
Expand Down Expand Up @@ -848,6 +861,7 @@ import {{invokerPackage}}.JSON;
{{/apiInfo}}
import java.util.Map;
import java.util.HashMap;
import java.util.List;

/**
* Response with status code {{code}} for the {{nickname}} operation
Expand All @@ -864,11 +878,13 @@ public class {{operationIdCamelCase}}{{code}}Response extends RuntimeException i
private final String body;
{{#dataType}}private final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} typedBody;{{/dataType}}
private final Map<String, String> headers;
private final Map<String, List<String>> multiValueHeaders;

private {{operationIdCamelCase}}{{code}}Response({{#dataType}}final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} body, {{/dataType}}final Map<String, String> headers) {
private {{operationIdCamelCase}}{{code}}Response({{#dataType}}final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} body, {{/dataType}}final Map<String, String> headers, final Map<String, List<String>> multiValueHeaders) {
{{#dataType}}this.typedBody = body;{{/dataType}}
this.body = {{#dataType}}{{#isPrimitiveType}}body{{/isPrimitiveType}}{{^isPrimitiveType}}body.toJson(){{/isPrimitiveType}}{{/dataType}}{{^dataType}}""{{/dataType}};
this.headers = headers;
this.multiValueHeaders = multiValueHeaders;
}

@Override
Expand All @@ -892,18 +908,30 @@ public class {{operationIdCamelCase}}{{code}}Response extends RuntimeException i
return this.headers;
}

@Override
public Map<String, List<String>> getMultiValueHeaders() {
return this.multiValueHeaders;
}

/**
* Create a {{operationIdCamelCase}}{{code}}Response with{{^dataType}}out{{/dataType}} a body
*/
public static {{operationIdCamelCase}}{{code}}Response of({{#dataType}}final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} body{{/dataType}}) {
return new {{operationIdCamelCase}}{{code}}Response({{#dataType}}body, {{/dataType}}new HashMap<>());
return new {{operationIdCamelCase}}{{code}}Response({{#dataType}}body, {{/dataType}}new HashMap<>(), new HashMap<>());
}

/**
* Create a {{operationIdCamelCase}}{{code}}Response with{{^dataType}}out{{/dataType}} a body and headers
*/
public static {{operationIdCamelCase}}{{code}}Response of({{#dataType}}final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} body, {{/dataType}}final Map<String, String> headers) {
return new {{operationIdCamelCase}}{{code}}Response({{#dataType}}body, {{/dataType}}headers);
return new {{operationIdCamelCase}}{{code}}Response({{#dataType}}body, {{/dataType}}headers, new HashMap<>());
}

/**
* Create a {{operationIdCamelCase}}{{code}}Response with{{^dataType}}out{{/dataType}} a body, headers and multi-value headers
*/
public static {{operationIdCamelCase}}{{code}}Response of({{#dataType}}final {{#isPrimitiveType}}String{{/isPrimitiveType}}{{^isPrimitiveType}}{{.}}{{/isPrimitiveType}} body, {{/dataType}}final Map<String, String> headers, final Map<String, List<String>> multiValueHeaders) {
return new {{operationIdCamelCase}}{{code}}Response({{#dataType}}body, {{/dataType}}headers, multiValueHeaders);
}
}
{{/responses}}
Expand Down Expand Up @@ -1276,7 +1304,7 @@ public abstract class {{operationIdCamelCase}} implements RequestHandler<APIGate
// Initialise instance of Gson and prime serialisation and deserialisation
new JSON();
JSON.getGson().fromJson(JSON.getGson().toJson(new ApiResponse("", 0, new HashMap<>())), ApiResponse.class);
JSON.getGson().fromJson(JSON.getGson().toJson(new ApiResponse("", 0, new HashMap<>(), new HashMap<>())), ApiResponse.class);
try {
// Prime input validation - this will likely fail for the fake event but ensures the code path is optimised
Expand Down Expand Up @@ -1358,6 +1386,7 @@ public abstract class {{operationIdCamelCase}} implements RequestHandler<APIGate
return new APIGatewayProxyResponseEvent()
.withStatusCode(response.getStatusCode())
.withHeaders(responseHeaders)
.withMultiValueHeaders(response.getMultiValueHeaders())
.withBody(response.getBody());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def parse_body(body, content_types, model):
"""
if len([c for c in content_types if c != 'application/json']) == 0:
if model != Any:
body = model.from_json(body)
body = model.model_validate(json.loads(body))
else:
body = json.loads(body or '{}')
return body
Expand Down Expand Up @@ -178,6 +178,7 @@ class ApiResponse(Exception, Generic[StatusCode, ResponseBody]):
status_code: StatusCode
headers: Dict[str, str]
body: ResponseBody
multi_value_headers: Optional[Dict[str, List[str]]] = None
class HandlerChain(Generic[RequestParameters, RequestBody, StatusCode, ResponseBody]):
def next(self, request: ChainedApiRequest[RequestParameters, RequestBody]) -> ApiResponse[StatusCode, ResponseBody]:
Expand Down Expand Up @@ -349,6 +350,7 @@ def {{operationId}}_handler(_handler: {{operationIdCamelCase}}HandlerFunction =
return {
'statusCode': response.status_code,
'headers': response_headers,
'multiValueHeaders': response.multi_value_headers or {},
'body': response_body,
}
return wrapper
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TypeVar, Generic, Dict
from typing import TypeVar, Generic, Dict, List
from {{packageName}}.api.operation_config import ApiResponse

ResponseBody = TypeVar("ResponseBody")
Expand All @@ -9,36 +9,36 @@ class Response(Generic[ResponseBody]):
"""

@staticmethod
def success(body: ResponseBody, headers: Dict[str, str] = {}) -> ApiResponse[200, ResponseBody]:
def success(body: ResponseBody, headers: Dict[str, str] = {}, multi_value_headers: Dict[str, List[str]] = {}) -> ApiResponse[200, ResponseBody]:
"""
A successful response
"""
return ApiResponse(status_code=200, body=body, headers={**headers})
return ApiResponse(status_code=200, body=body, headers={**headers}, multi_value_headers={**multi_value_headers})
@staticmethod
def bad_request(body: ResponseBody, headers: Dict[str, str] = {}) -> ApiResponse[400, ResponseBody]:
def bad_request(body: ResponseBody, headers: Dict[str, str] = {}, multi_value_headers: Dict[str, List[str]] = {}) -> ApiResponse[400, ResponseBody]:
"""
A response which indicates a client error
"""
return ApiResponse(status_code=400, body=body, headers={**headers})
return ApiResponse(status_code=400, body=body, headers={**headers}, multi_value_headers={**multi_value_headers})
@staticmethod
def not_found(body: ResponseBody, headers: Dict[str, str] = {}) -> ApiResponse[404, ResponseBody]:
def not_found(body: ResponseBody, headers: Dict[str, str] = {}, multi_value_headers: Dict[str, List[str]] = {}) -> ApiResponse[404, ResponseBody]:
"""
A response which indicates the requested resource was not found
"""
return ApiResponse(status_code=404, body=body, headers={**headers})
return ApiResponse(status_code=404, body=body, headers={**headers}, multi_value_headers={**multi_value_headers})
@staticmethod
def not_authorized(body: ResponseBody, headers: Dict[str, str] = {}) -> ApiResponse[403, ResponseBody]:
def not_authorized(body: ResponseBody, headers: Dict[str, str] = {}, multi_value_headers: Dict[str, List[str]] = {}) -> ApiResponse[403, ResponseBody]:
"""
A response which indicates the caller is not authorised to perform the operation or access the resource
"""
return ApiResponse(status_code=403, body=body, headers={**headers})
return ApiResponse(status_code=403, body=body, headers={**headers}, multi_value_headers={**multi_value_headers})
@staticmethod
def internal_failure(body: ResponseBody, headers: Dict[str, str] = {}) -> ApiResponse[500, ResponseBody]:
def internal_failure(body: ResponseBody, headers: Dict[str, str] = {}, multi_value_headers: Dict[str, List[str]] = {}) -> ApiResponse[500, ResponseBody]:
"""
A response to indicate a server error
"""
return ApiResponse(status_code=500, body=body, headers={**headers})
return ApiResponse(status_code=500, body=body, headers={**headers}, multi_value_headers={**multi_value_headers})
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type OperationApiGatewayLambdaHandler<T extends OperationIds> = (event: APIGatew
export interface OperationResponse<StatusCode extends number, Body> {
statusCode: StatusCode;
headers?: { [key: string]: string };
multiValueHeaders?: { [key: string]: string[] };
body: Body;
}

Expand Down
Loading

0 comments on commit fd32e13

Please sign in to comment.