Skip to main content
Develop complete, testable functions locally and deploy them to see real results. This guide walks you through building functions you can actually test with live URLs.

🌐 Live Testing

Deploy functions and test them with real URLs on your hub

πŸ”„ Data Transformation

See your functions transform data in real-time

πŸ“ Complete Examples

Full function structures with all necessary files

πŸš€ Deploy & Test

From local development to live URL in minutes

Quick Start: Your First Testable Function

Let’s build a complete function that you can test with a real URL after deployment.
1

Set up your project

# Create project directory
mkdir weather-api && cd weather-api

# Initialize npm and install dependencies
npm init -y
npm install -D typescript @types/node @types/aws-lambda ts-node

# Create project structure
mkdir src lib types
2

Create your function files

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { validateCity, transformWeatherData } from './lib/weather';
import { createResponse, handleError } from './lib/utils';

export const handler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  try {
    console.log('Weather API called:', {
      method: event.httpMethod,
      path: event.path,
      query: event.queryStringParameters
    });

    const city = event.queryStringParameters?.city;
    
    // Validate input
    const validation = validateCity(city);
    if (!validation.isValid) {
      return createResponse(400, { 
        error: 'Invalid city name',
        details: validation.errors 
      });
    }

    // Get weather data (simulated for demo)
    const rawWeatherData = await fetchWeatherData(city!);
    
    // Transform the data
    const transformedData = transformWeatherData(rawWeatherData);
    
    return createResponse(200, {
      city: city,
      weather: transformedData,
      timestamp: new Date().toISOString(),
      source: 'Ollie Hub Weather API'
    });
    
  } catch (error) {
    console.error('Weather API error:', error);
    return handleError(error);
  }
};

// Simulate weather API call
async function fetchWeatherData(city: string) {
  // Simulate API delay
  await new Promise(resolve => setTimeout(resolve, 100));
  
  // Return mock weather data
  return {
    temperature: Math.floor(Math.random() * 30) + 10,
    humidity: Math.floor(Math.random() * 40) + 40,
    conditions: ['sunny', 'cloudy', 'rainy', 'windy'][Math.floor(Math.random() * 4)],
    pressure: 1013 + Math.floor(Math.random() * 20) - 10,
    windSpeed: Math.floor(Math.random() * 20),
    rawTimestamp: Date.now()
  };
}
3

Test locally

Create a test file to verify your function works:
test.ts
import { handler } from './index';
import { APIGatewayProxyEvent } from 'aws-lambda';

async function testWeatherAPI() {
  console.log('πŸ§ͺ Testing Weather API Function\n');
  
  // Test valid city
  const validEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'GET',
    path: '/weather',
    queryStringParameters: { city: 'London' },
    headers: {},
    body: null
  };
  
  console.log('Testing with city: London');
  const result1 = await handler(validEvent as APIGatewayProxyEvent);
  console.log('Status:', result1.statusCode);
  console.log('Response:', JSON.parse(result1.body));
  console.log('\n---\n');
  
  // Test invalid city
  const invalidEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'GET',
    path: '/weather',
    queryStringParameters: { city: 'X' },
    headers: {},
    body: null
  };
  
  console.log('Testing with invalid city: X');
  const result2 = await handler(invalidEvent as APIGatewayProxyEvent);
  console.log('Status:', result2.statusCode);
  console.log('Response:', JSON.parse(result2.body));
  console.log('\n---\n');
  
  // Test missing city
  const missingEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'GET',
    path: '/weather',
    queryStringParameters: null,
    headers: {},
    body: null
  };
  
  console.log('Testing with missing city parameter');
  const result3 = await handler(missingEvent as APIGatewayProxyEvent);
  console.log('Status:', result3.statusCode);
  console.log('Response:', JSON.parse(result3.body));
  
  console.log('\nβœ… Local testing completed!');
}

testWeatherAPI().catch(console.error);
Run the test:
npm test
4

Deploy and test live

  1. Upload to Ollie Hub: Zip your function folder and upload it via the web interface
  2. Get your function URL: Copy the URL from your function dashboard
  3. Test with real URLs:
# Replace YOUR_FUNCTION_URL with your actual function URL

# Test valid city
curl "YOUR_FUNCTION_URL?city=Paris"

# Test another city to see different data
curl "YOUR_FUNCTION_URL?city=Tokyo"

# Test error handling
curl "YOUR_FUNCTION_URL?city=X"

# Test missing parameter
curl "YOUR_FUNCTION_URL"
Expected response for Paris:
{
  "city": "Paris",
  "weather": {
    "temp": {
      "celsius": 22,
      "fahrenheit": 72,
      "description": "Mild"
    },
    "humidity": {
      "percentage": 65,
      "level": "Moderate"
    },
    "conditions": {
      "current": "sunny",
      "emoji": "β˜€οΈ"
    },
    "wind": {
      "speed": 8,
      "description": "Light breeze"
    },
    "comfort": {
      "score": 85,
      "rating": "Excellent"
    }
  },
  "timestamp": "2024-01-15T10:30:00.000Z",
  "source": "Ollie Hub Weather API"
}

Advanced Example: User Data Processor

Build a more complex function that processes and transforms user data:
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { validateUserData, processUser, generateUserStats } from './lib/userProcessor';
import { createResponse, handleError } from './lib/utils';

export const handler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  try {
    console.log('User processor called:', {
      method: event.httpMethod,
      path: event.path
    });

    if (event.httpMethod === 'GET') {
      return createResponse(200, {
        message: 'User Data Processor API',
        endpoints: {
          process: 'POST /process - Process user data',
          stats: 'GET /stats?users=number - Generate user statistics'
        },
        example: {
          url: 'POST YOUR_FUNCTION_URL',
          body: {
            name: 'John Doe',
            email: 'john@example.com',
            age: 28,
            interests: ['technology', 'sports'],
            location: 'New York'
          }
        }
      });
    }

    if (event.httpMethod === 'POST') {
      const userData = JSON.parse(event.body || '{}');
      
      // Validate user data
      const validation = validateUserData(userData);
      if (!validation.isValid) {
        return createResponse(400, {
          error: 'Invalid user data',
          details: validation.errors
        });
      }

      // Process and transform user data
      const processedUser = processUser(userData);
      
      return createResponse(200, {
        original: userData,
        processed: processedUser,
        transformation: {
          added: ['id', 'slug', 'category', 'score', 'recommendations'],
          computed: ['ageGroup', 'riskLevel', 'primaryInterest'],
          formatted: ['email', 'name', 'location']
        }
      });
    }

    // Handle stats endpoint
    if (event.path?.includes('stats')) {
      const userCount = parseInt(event.queryStringParameters?.users || '10');
      const stats = generateUserStats(userCount);
      
      return createResponse(200, {
        stats,
        generated: userCount,
        timestamp: new Date().toISOString()
      });
    }

    return createResponse(405, { error: 'Method not allowed' });
    
  } catch (error) {
    return handleError(error);
  }
};

Test the User Processor

test-user-processor.ts
import { handler } from './index';
import { APIGatewayProxyEvent } from 'aws-lambda';

async function testUserProcessor() {
  console.log('πŸ§ͺ Testing User Data Processor\n');
  
  // Test API info
  const infoEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'GET',
    path: '/',
    queryStringParameters: null,
    headers: {},
    body: null
  };
  
  console.log('1. Getting API information:');
  const infoResult = await handler(infoEvent as APIGatewayProxyEvent);
  console.log('Response:', JSON.parse(infoResult.body));
  console.log('\n---\n');
  
  // Test user processing
  const userData = {
    name: 'Alice Johnson',
    email: 'alice@example.com',
    age: 28,
    interests: ['technology', 'travel', 'photography'],
    location: 'San Francisco'
  };
  
  const processEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'POST',
    path: '/process',
    body: JSON.stringify(userData),
    headers: { 'Content-Type': 'application/json' },
    queryStringParameters: null
  };
  
  console.log('2. Processing user data:');
  console.log('Input:', userData);
  const processResult = await handler(processEvent as APIGatewayProxyEvent);
  console.log('Output:', JSON.parse(processResult.body));
  console.log('\n---\n');
  
  // Test stats generation
  const statsEvent: Partial<APIGatewayProxyEvent> = {
    httpMethod: 'GET',
    path: '/stats',
    queryStringParameters: { users: '100' },
    headers: {},
    body: null
  };
  
  console.log('3. Generating user statistics:');
  const statsResult = await handler(statsEvent as APIGatewayProxyEvent);
  console.log('Stats:', JSON.parse(statsResult.body));
  
  console.log('\nβœ… All tests completed!');
}

testUserProcessor().catch(console.error);

Real-World Data Transformation Examples

Deployment Checklist

1

Local testing passes

βœ… All functions run without errors locally
βœ… Data transformation works as expected
βœ… Error handling catches edge cases
βœ… TypeScript compiles without warnings
2

Function structure is correct

βœ… index.ts exists with exported handler
βœ… package.json includes all dependencies
βœ… Helper files are properly structured
βœ… No sensitive data in source code
3

Upload and configure

βœ… Function uploaded to Ollie Hub
βœ… Environment variables configured
βœ… Function type set correctly (Request/Task/Response)
βœ… Memory and timeout settings appropriate
4

Live testing

βœ… Function URL accessible
βœ… Data transformation works on live data
βœ… Error responses are user-friendly
βœ… Performance is acceptable

Next Steps

Deploy Your Function

Learn how to deploy your functions to Ollie Hub

Environment Variables

Securely manage configuration and API keys

Function Types

Understand Request, Response, and Task functions

Examples Gallery

Explore more real-world function examples
Ready to Build? Start with the Weather API example above - it’s designed to work immediately and show you real data transformation. You’ll have a working function with a testable URL in under 10 minutes!