Skip to content

code-caffeine-shekhawat4u/API-Development-and-Integration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

API Development & Integration

Training Session for Code Caffeine Interns

What is an API?

Application Programming Interface (API) is a set of rules and protocols that allows different software applications to communicate with each other. Think of it as a waiter in a restaurant who takes your order to the kitchen and brings back your food.

Why APIs Matter

  • Separation of Concerns: Frontend and backend can be developed independently
  • Scalability: Multiple applications can use the same API
  • Flexibility: Different frontends (web, mobile, desktop) can use the same backend
  • Team Collaboration: Web developers and Python developers can work together seamlessly

REST API Fundamentals

What is REST?

REST (Representational State Transfer) is an architectural style for designing networked applications. It uses standard HTTP methods to perform operations on resources.

HTTP Methods

  • GET: Retrieve data (Read)
  • POST: Create new data (Create)
  • PUT: Update existing data (Update/Replace)
  • PATCH: Partially update data (Partial Update)
  • DELETE: Remove data (Delete)

HTTP Status Codes

  • 200 OK: Success
  • 201 Created: Resource created successfully
  • 400 Bad Request: Invalid request data
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Resource doesn't exist
  • 500 Internal Server Error: Server error

Building APIs with Python

Using Flask (Simple Example)

from flask import Flask, request, jsonify

app = Flask(__name__)

# Sample data
users = [
    {"id": 1, "name": "Alice", "email": "alice@example.com"},
    {"id": 2, "name": "Bob", "email": "bob@example.com"}
]

# GET all users
@app.route('/api/users', methods=['GET'])
def get_users():
    return jsonify(users)

# GET single user
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = next((u for u in users if u['id'] == user_id), None)
    if user:
        return jsonify(user)
    return jsonify({"error": "User not found"}), 404

# POST new user
@app.route('/api/users', methods=['POST'])
def create_user():
    data = request.get_json()
    new_user = {
        "id": len(users) + 1,
        "name": data.get('name'),
        "email": data.get('email')
    }
    users.append(new_user)
    return jsonify(new_user), 201

if __name__ == '__main__':
    app.run(debug=True)

Using FastAPI (Modern Alternative)

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    name: str
    email: str

class UserResponse(BaseModel):
    id: int
    name: str
    email: str

users = [
    {"id": 1, "name": "Alice", "email": "alice@example.com"},
    {"id": 2, "name": "Bob", "email": "bob@example.com"}
]

@app.get("/api/users")
def get_users():
    return users

@app.post("/api/users", response_model=UserResponse)
def create_user(user: User):
    new_user = {
        "id": len(users) + 1,
        "name": user.name,
        "email": user.email
    }
    users.append(new_user)
    return new_user

Consuming APIs with JavaScript

Using Fetch API

// GET request
async function getUsers() {
    try {
        const response = await fetch('/api/users');
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        const users = await response.json();
        console.log(users);
        return users;
    } catch (error) {
        console.error('Error fetching users:', error);
    }
}

// POST request
async function createUser(userData) {
    try {
        const response = await fetch('/api/users', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(userData)
        });
        
        if (!response.ok) {
            throw new Error('Failed to create user');
        }
        
        const newUser = await response.json();
        console.log('User created:', newUser);
        return newUser;
    } catch (error) {
        console.error('Error creating user:', error);
    }
}

// Usage
getUsers();
createUser({ name: "Charlie", email: "charlie@example.com" });

Using Axios (Popular Library)

// GET request
axios.get('/api/users')
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

// POST request
axios.post('/api/users', {
    name: "Diana",
    email: "diana@example.com"
})
.then(response => {
    console.log('User created:', response.data);
})
.catch(error => {
    console.error('Error:', error);
});

Authentication & Security

JWT (JSON Web Tokens)

# Python (Flask-JWT-Extended)
from flask_jwt_extended import JWTManager, create_access_token, jwt_required

app.config['JWT_SECRET_KEY'] = 'your-secret-key'
jwt = JWTManager(app)

@app.route('/api/login', methods=['POST'])
def login():
    # Verify credentials (simplified)
    username = request.json.get('username')
    password = request.json.get('password')
    
    if username == 'admin' and password == 'password':
        access_token = create_access_token(identity=username)
        return jsonify(access_token=access_token)
    
    return jsonify({"error": "Invalid credentials"}), 401

@app.route('/api/protected', methods=['GET'])
@jwt_required()
def protected():
    return jsonify({"message": "This is a protected route"})
// JavaScript - Storing and using tokens
localStorage.setItem('token', response.data.access_token);

// Include token in requests
const token = localStorage.getItem('token');
fetch('/api/protected', {
    headers: {
        'Authorization': `Bearer ${token}`
    }
})

Best Practices

API Design

  1. Use clear, descriptive URLs: /api/users/123 not /api/getUser?id=123
  2. Use HTTP methods correctly: GET for reading, POST for creating
  3. Return consistent response formats
  4. Include proper error messages
  5. Version your APIs: /api/v1/users

Error Handling

# Python
@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Resource not found"}), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({"error": "Internal server error"}), 500
// JavaScript
function handleApiError(error) {
    if (error.response) {
        // Server responded with error status
        console.error('API Error:', error.response.status, error.response.data);
    } else if (error.request) {
        // Request made but no response
        console.error('Network Error:', error.request);
    } else {
        // Something else happened
        console.error('Error:', error.message);
    }
}

Input Validation

# Python with Pydantic (FastAPI)
from pydantic import BaseModel, validator

class User(BaseModel):
    name: str
    email: str
    age: int
    
    @validator('email')
    def validate_email(cls, v):
        if '@' not in v:
            raise ValueError('Invalid email format')
        return v
    
    @validator('age')
    def validate_age(cls, v):
        if v < 0 or v > 150:
            raise ValueError('Age must be between 0 and 150')
        return v

Testing APIs

Python Testing with pytest

import pytest
from your_app import app

@pytest.fixture
def client():
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

def test_get_users(client):
    response = client.get('/api/users')
    assert response.status_code == 200
    assert len(response.get_json()) >= 0

def test_create_user(client):
    user_data = {"name": "Test User", "email": "test@example.com"}
    response = client.post('/api/users', json=user_data)
    assert response.status_code == 201
    assert response.get_json()['name'] == "Test User"

JavaScript Testing with Jest

// Mock fetch for testing
global.fetch = jest.fn();

test('should fetch users successfully', async () => {
    const mockUsers = [
        { id: 1, name: 'Alice', email: 'alice@example.com' }
    ];
    
    fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => mockUsers
    });
    
    const users = await getUsers();
    expect(users).toEqual(mockUsers);
    expect(fetch).toHaveBeenCalledWith('/api/users');
});

Practical Exercise

For Python Developers

Create a simple API with the following endpoints:

  • GET /api/books - List all books
  • GET /api/books/{id} - Get a specific book
  • POST /api/books - Create a new book
  • PUT /api/books/{id} - Update a book
  • DELETE /api/books/{id} - Delete a book

For Web Developers

Create a simple frontend that:

  • Displays a list of books from the API
  • Has a form to add new books
  • Allows editing existing books
  • Provides delete functionality

Working Together

  • Python developers create the API
  • Web developers create the frontend
  • Test the integration together
  • Handle errors gracefully on both sides

Tools & Resources

Development Tools

  • Postman: Test API endpoints
  • Insomnia: Alternative API testing tool
  • Thunder Client: VS Code extension for API testing
  • Swagger/OpenAPI: API documentation

Python Libraries

  • Flask: Lightweight web framework
  • FastAPI: Modern, fast API framework
  • Requests: HTTP library for making API calls
  • SQLAlchemy: Database ORM

JavaScript Libraries

  • Axios: HTTP client library
  • Fetch API: Built-in browser API
  • SWR/React Query: Data fetching libraries for React

Key Takeaways

  1. APIs are the bridge between frontend and backend applications
  2. REST principles provide a standard way to design APIs
  3. Both Python and JavaScript developers need to understand API concepts
  4. Security and validation are crucial for production APIs
  5. Testing ensures your APIs work correctly
  6. Documentation helps other developers use your APIs
  7. Error handling improves user experience

Next Steps

  • Practice building simple APIs with Python
  • Practice consuming APIs with JavaScript
  • Learn about GraphQL as an alternative to REST
  • Explore microservices architecture
  • Study API security in depth
  • Learn about API rate limiting and caching

Remember: The best way to learn APIs is by building and using them. Start small, practice regularly, and gradually tackle more complex scenarios!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors