API Integration
There are two methods to create an API with Lambda integration, via Lambda proxy integration or Lambda non-proxy integration.
Lamda Proxy Integration
The Lambda proxy integration allows the client to call a single Lambda function in the backend.
In Lambda proxy integration, when the client makes a request, the API Gateway forwards the request to Lambda without transforming/modifying it. When a client submits an API request, API Gateway passes to the integrated Lambda function the raw request as-is. This request data includes the request headers, query string parameters, URL path variables, payload, and API configuration data.
This is helpful in my project in that I can easily access the URL path variables by parsing event.path to retrieve information on what page the user wants to pull up. (Web URL Structure: domain/condition/trial name/number)

For API Gateway to pass the Lambda output as the API response to the client, the Lambda function must return the result in this format.

Notes: The response body must be a string, whereas I want to return data from the DynamoDB table as a JSON response.
Update: Was informed that you can convert JSON to string using stringify() then back with JSON.parse(). However, I'm a little concerned about any data getting "mistranslated".
Lamda Non-Proxy Integration
In Lambda non-proxy integration, when the client makes a request, the API Gateway is able to transform it and then forwards it to the lambda. Similarly, when the response data comes from the lambda function to the API Gateway, it sets the header, status code etc.
Lambda function for the Lambda custom integration only takes input from the API Gateway API integration request body, provided that API Gateway maps the required API request parameters to the integration request body before forwarding the client request to the backend. For this to happen, the API developer must create a mapping template and configure it on the API method when creating the API.

The function can return an output of any JSON object, a string, a number, a Boolean, or even a binary blob.
Notes: According to StackOverflow, Lambda Non-Proxy Integration involves a lot more of work to set it up, but it allows the developer to decouple what the lambda receives and returns, and how it gets mapped to different HTTP status codes, headers, and payloads. According to Rick Haffey, "Using Proxy Integration forces (at least a subset of) that responsibility onto the Lambda function. (i.e. knowing how to interpret and decide on HTTP headers, query parameters, status codes, etc.). In doing that, I feel that it muddies the responsibility of the backing Lambda function -- Lambda now needs to both handle whatever "business" logic it's being called to do, and also handle interpreting the incoming HTTP values and decide on the outgoing HTTP response values." Also what my supervisor said :). In the long run, most developers seem to prefer non-proxy integration over proxy integration, so I would rather set it up now rather than use proxy integration and have to rebuild the API later.