Even though Netlify Functions are designed for simple logic, sometimes boilerplate code needs to be tidied up. For such a situation, I have prepared few methods that increase the readability of the code and facilitate work with the Netlify environment. I used TypeScript in the examples, but similar logic can be applied to other languages as well.

1. Simple wrappers for different responses

// utils.ts
export const OK_200 = (data: any) => ({
  statusCode: 200,
  body: JSON.stringify(data),
  headers: { "access-control-allow-origin": "*" },
})

export const NO_500 = (data: any) => ({
  statusCode: 500,
  body: JSON.stringify(data),
  headers: { "access-control-allow-origin": "*" },
})

2. Extract query string params with a hook-like syntaxt

// utils.ts
export const getParams = (event, params: string[]): string[] => {
  const values = [] as string[];
  for (let param of params) {
    const value = event.queryStringParameters[param]
    if (!value) throw new Error('missing params');
    values.push(value);
  }
  return values;
}

// usage
export const handler: Handler = async (event, context) => {
  const [ user, email ] = getParams(event, [ 'user', 'email' ]);
  // some custom logic
  return { msg: 'success' };
}

3. Universal try–catch wrapper for handlers

// utils.ts
export const tryCatch = (func: Function) => async (event, context) => {
  try {
    return OK_200(await func(event, context))
  } catch (err) {
    console.log(err);
    return NO_500({ message: err.message });
  } 
}

// usage
export const handler: Handler = tryCatch(async (event, context) => {
  const [ user ] = getParams(event, ['user']);
  if (user !== 'jasiek') throw new Error('wrong user!');  
  return { msg: 'success' };
})