localhost/api
http://localhost/api
The localhost/api path is the standard convention for REST API endpoints in web applications. APIs (Application Programming Interfaces) allow different software systems to communicate, typically using JSON or XML data formats over HTTP.
→ Open localhost/api
Common API URL Patterns
- localhost/api - API base path
- localhost/api/users - Users resource
- localhost/api/v1/products - Versioned API
- localhost/api/auth/login - Authentication endpoint
- localhost/api/posts/:id - Resource with parameter
- localhost:3000/api - Node.js API server
- localhost:8000/api - Django/Python API
- localhost/api/v2/orders - API version 2
REST API HTTP Methods
| Method |
Purpose |
Example |
| GET |
Retrieve data |
GET /api/users |
| POST |
Create new resource |
POST /api/users |
| PUT |
Update entire resource |
PUT /api/users/123 |
| PATCH |
Partial update |
PATCH /api/users/123 |
| DELETE |
Remove resource |
DELETE /api/users/123 |
Create REST API with Node.js/Express
// api-server.js
const express = require('express');
const app = express();
const PORT = 3000;
// Middleware
app.use(express.json());
// CORS handling
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// Sample data
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];
// API Routes
// GET all users
app.get('/api/users', (req, res) => {
res.json({ success: true, data: users });
});
// GET single user
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ success: false, message: 'User not found' });
}
res.json({ success: true, data: user });
});
// POST create user
app.post('/api/users', (req, res) => {
const newUser = {
id: users.length + 1,
name: req.body.name,
email: req.body.email
};
users.push(newUser);
res.status(201).json({ success: true, data: newUser });
});
// PUT update user
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ success: false, message: 'User not found' });
}
user.name = req.body.name;
user.email = req.body.email;
res.json({ success: true, data: user });
});
// DELETE user
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ success: false, message: 'User not found' });
}
users.splice(index, 1);
res.json({ success: true, message: 'User deleted' });
});
// Root endpoint
app.get('/api', (req, res) => {
res.json({
message: 'API is running',
version: '1.0.0',
endpoints: {
users: '/api/users',
posts: '/api/posts'
}
});
});
app.listen(PORT, () => {
console.log(`API server running on http://localhost:${PORT}/api`);
});
// Run: node api-server.js
// Access: http://localhost:3000/api
Create REST API with PHP
<?php
// api/index.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type');
// Database connection
$conn = mysqli_connect("localhost", "root", "", "myapp");
// Get request method and path
$method = $_SERVER['REQUEST_METHOD'];
$request = explode('/', trim($_SERVER['PATH_INFO'] ?? '', '/'));
// Route: /api/users
if ($request[0] === 'users') {
switch ($method) {
case 'GET':
if (isset($request[1])) {
// Get single user
$id = intval($request[1]);
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = $id");
$user = mysqli_fetch_assoc($result);
echo json_encode(['success' => true, 'data' => $user]);
} else {
// Get all users
$result = mysqli_query($conn, "SELECT * FROM users");
$users = mysqli_fetch_all($result, MYSQLI_ASSOC);
echo json_encode(['success' => true, 'data' => $users]);
}
break;
case 'POST':
// Create user
$data = json_decode(file_get_contents('php://input'), true);
$name = mysqli_real_escape_string($conn, $data['name']);
$email = mysqli_real_escape_string($conn, $data['email']);
$query = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
if (mysqli_query($conn, $query)) {
$id = mysqli_insert_id($conn);
echo json_encode([
'success' => true,
'data' => ['id' => $id, 'name' => $name, 'email' => $email]
]);
}
break;
case 'PUT':
// Update user
$id = intval($request[1]);
$data = json_decode(file_get_contents('php://input'), true);
$name = mysqli_real_escape_string($conn, $data['name']);
$email = mysqli_real_escape_string($conn, $data['email']);
$query = "UPDATE users SET name='$name', email='$email' WHERE id=$id";
mysqli_query($conn, $query);
echo json_encode(['success' => true, 'message' => 'User updated']);
break;
case 'DELETE':
// Delete user
$id = intval($request[1]);
mysqli_query($conn, "DELETE FROM users WHERE id=$id");
echo json_encode(['success' => true, 'message' => 'User deleted']);
break;
}
} else {
// Root API endpoint
echo json_encode([
'message' => 'API is running',
'version' => '1.0.0',
'endpoints' => [
'users' => '/api/users'
]
]);
}
// .htaccess file for clean URLs
// RewriteEngine On
// RewriteCond %{REQUEST_FILENAME} !-f
// RewriteRule ^(.*)$ index.php [QSA,L]
?>
Test API with curl
# GET all users
curl http://localhost/api/users
# GET single user
curl http://localhost/api/users/1
# POST create user
curl -X POST http://localhost/api/users \
-H "Content-Type: application/json" \
-d '{"name":"Alice","email":"alice@example.com"}'
# PUT update user
curl -X PUT http://localhost/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"John Updated","email":"john.new@example.com"}'
# DELETE user
curl -X DELETE http://localhost/api/users/1
# Pretty print JSON
curl http://localhost/api/users | json_pp
# Include response headers
curl -i http://localhost/api/users
# Verbose output
curl -v http://localhost/api/users
Test API with JavaScript (fetch)
// GET request
fetch('http://localhost/api/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// POST request
fetch('http://localhost/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Alice',
email: 'alice@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
// PUT request
fetch('http://localhost/api/users/1', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Updated',
email: 'john.new@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
// DELETE request
fetch('http://localhost/api/users/1', {
method: 'DELETE'
})
.then(response => response.json())
.then(data => console.log(data));
// Using async/await
async function getUsers() {
try {
const response = await fetch('http://localhost/api/users');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
Fix CORS Errors
CORS (Cross-Origin Resource Sharing) errors occur when frontend on one port tries to access API on different port.
Node.js/Express CORS
// Install cors package
npm install cors
// api-server.js
const express = require('express');
const cors = require('cors');
const app = express();
// Enable CORS for all routes
app.use(cors());
// Or configure specific origins
app.use(cors({
origin: 'http://localhost:3000',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));
// Or manual CORS headers
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
// Handle preflight
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
PHP CORS Headers
<?php
// At top of API file
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
?>
API Authentication with JWT
// Install jsonwebtoken
npm install jsonwebtoken
// auth-api.js
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const SECRET_KEY = 'your-secret-key';
app.use(express.json());
// Login endpoint
app.post('/api/auth/login', (req, res) => {
const { username, password } = req.body;
// Validate credentials (use database in production)
if (username === 'admin' && password === 'password') {
// Generate JWT token
const token = jwt.sign(
{ username, role: 'admin' },
SECRET_KEY,
{ expiresIn: '24h' }
);
res.json({ success: true, token });
} else {
res.status(401).json({ success: false, message: 'Invalid credentials' });
}
});
// Middleware to verify token
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) {
return res.status(401).json({ success: false, message: 'Token required' });
}
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) {
return res.status(403).json({ success: false, message: 'Invalid token' });
}
req.user = user;
next();
});
}
// Protected route
app.get('/api/protected', authenticateToken, (req, res) => {
res.json({
success: true,
message: 'Protected data',
user: req.user
});
});
// Client usage
// Login
fetch('http://localhost:3000/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'password' })
})
.then(res => res.json())
.then(data => {
localStorage.setItem('token', data.token);
});
// Access protected route
const token = localStorage.getItem('token');
fetch('http://localhost:3000/api/protected', {
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => res.json())
.then(data => console.log(data));
API Response Standards
// Success response
{
"success": true,
"data": {
"id": 1,
"name": "John Doe"
}
}
// Error response
{
"success": false,
"error": {
"code": "USER_NOT_FOUND",
"message": "User with ID 123 not found"
}
}
// List response with pagination
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"pages": 10
}
}
// HTTP Status Codes
// 200 OK - Success
// 201 Created - Resource created
// 204 No Content - Success, no response body
// 400 Bad Request - Invalid input
// 401 Unauthorized - Authentication required
// 403 Forbidden - No permission
// 404 Not Found - Resource doesn't exist
// 500 Internal Server Error - Server error
API Testing Tools
- Postman - Popular API testing tool with GUI
- Insomnia - Lightweight API client
- curl - Command-line HTTP client
- HTTPie - User-friendly curl alternative
- Thunder Client - VS Code extension
- REST Client - VS Code extension
- Swagger/OpenAPI - API documentation and testing
Best Practice:
Version your APIs (v1, v2) to maintain backward compatibility. Use semantic versioning and document all endpoints with tools like Swagger for better developer experience.
Frequently Asked Questions
What is localhost/api used for?
It's the standard path for REST API endpoints, allowing frontend applications to communicate with backend services using HTTP requests to retrieve or manipulate data.
How do I test API endpoints locally?
Use tools like Postman, Insomnia, curl, or browser DevTools. You can also test directly in browser for GET requests or use JavaScript fetch() in console.
Why do I get CORS errors?
CORS errors occur when frontend (e.g., localhost:3000) tries to access API on different origin (localhost:8000). Fix by adding CORS headers to API server.
How do I secure my API?
Use authentication (JWT tokens), validate all inputs, implement rate limiting, use HTTPS in production, and never expose sensitive data or API keys.
What's the difference between REST and GraphQL?
REST uses multiple endpoints with HTTP methods, GraphQL uses single endpoint with query language. REST is simpler, GraphQL offers more flexibility for complex queries.
Related URLs and Resources