Ускорьте разработку в 2 раза. Работайте параллельно с Frontend. Получайте ранний фидбек. Contract-First Development из коробки.
Contract-First Development с LightBox API
Спроектируйте API контракт. Согласуйте с командой. Одна спецификация — источник истины для всех.
⏱ 15 минутЗагрузите спецификацию. Автоматически создаются все эндпоинты. Настройте примеры данных.
⏱ 2-5 минутОтправьте URL команде. Frontend разрабатывает с моками. Никто не ждет. Обе команды работают параллельно.
⏱ Сразу жеРазрабатывайте на основе контракта. Получайте ранний фидбек от Frontend. Плавная замена моков на реальный API.
⏱ Без блокировокРеальные кейсы использования LightBox API в Backend разработке
Frontend ждет Backend 1-2 недели. Срываются дедлайны.
OpenAPI → LightBox → обе команды работают сразу. Экономия 1-2 недель.
Клиент хочет демо до разработки. Реализация займет 2 недели.
Прототип в LightBox за 1 час. Ранний фидбек. Избежание переделок.
Внешний API дорогой, нестабильный, имеет rate limiting.
Моки в LightBox. Разработка без ограничений. Экономия $500-1000.
Service A зависит от Service B и C, которые еще не готовы.
Моки отсутствующих сервисов. Независимая разработка. Нет блокировок.
Готовые примеры кода для быстрой интеграции с LightBox API
// config/api.js
const config = {
development: {
apiUrl: process.env.LIGHTBOX_API_URL || 'https://lightboxapi.com/myproject'
},
production: {
apiUrl: process.env.PROD_API_URL || 'https://api.myapp.com'
}
};
module.exports = config[process.env.NODE_ENV || 'development'];
// services/userService.js
const axios = require('axios');
const config = require('../config/api');
class UserService {
constructor() {
this.baseURL = config.apiUrl;
this.client = axios.create({
baseURL: this.baseURL,
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
}
async getUsers() {
try {
const response = await this.client.get('/api/users');
return response.data;
} catch (error) {
console.error('Error fetching users:', error);
throw error;
}
}
async getUserById(id) {
const response = await this.client.get(`/api/users/${id}`);
return response.data;
}
async createUser(userData) {
const response = await this.client.post('/api/users', userData);
return response.data;
}
async updateUser(id, userData) {
const response = await this.client.put(`/api/users/${id}`, userData);
return response.data;
}
}
module.exports = new UserService();
// Использование в контроллере
// routes/users.js
const express = require('express');
const router = express.Router();
const userService = require('../services/userService');
router.get('/users', async (req, res) => {
try {
const users = await userService.getUsers();
res.json(users);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
router.post('/users', async (req, res) => {
try {
const user = await userService.createUser(req.body);
res.status(201).json(user);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = router;
# settings.py
import os
# LightBox API Configuration
LIGHTBOX_API_URL = os.getenv(
'LIGHTBOX_API_URL',
'https://lightboxapi.com/myproject'
)
# Автоматическое переключение API
API_BASE_URL = os.getenv(
'API_BASE_URL',
LIGHTBOX_API_URL if DEBUG else 'https://api.myapp.com'
)
# services/api_client.py
import requests
from django.conf import settings
from typing import Dict, List, Optional
class APIClient:
"""Клиент для работы с API"""
def __init__(self):
self.base_url = settings.API_BASE_URL
self.session = requests.Session()
self.session.headers.update({
'Content-Type': 'application/json',
'Accept': 'application/json'
})
def _make_request(self, method: str, endpoint: str, **kwargs):
"""Базовый метод для выполнения запросов"""
url = f'{self.base_url}{endpoint}'
try:
response = self.session.request(method, url, **kwargs)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f'API Error: {e}')
raise
def get_users(self) -> List[Dict]:
"""Получить список пользователей"""
return self._make_request('GET', '/api/users')
def get_user(self, user_id: int) -> Dict:
"""Получить пользователя по ID"""
return self._make_request('GET', f'/api/users/{user_id}')
def create_user(self, user_data: Dict) -> Dict:
"""Создать нового пользователя"""
return self._make_request('POST', '/api/users', json=user_data)
def update_user(self, user_id: int, user_data: Dict) -> Dict:
"""Обновить данные пользователя"""
return self._make_request('PUT', f'/api/users/{user_id}', json=user_data)
def delete_user(self, user_id: int) -> None:
"""Удалить пользователя"""
self._make_request('DELETE', f'/api/users/{user_id}')
# Singleton instance
api_client = APIClient()
# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from .services.api_client import api_client
import json
@require_http_methods(["GET"])
def list_users(request):
"""Получить список пользователей"""
try:
users = api_client.get_users()
return JsonResponse(users, safe=False)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
@require_http_methods(["POST"])
def create_user(request):
"""Создать пользователя"""
try:
user_data = json.loads(request.body)
user = api_client.create_user(user_data)
return JsonResponse(user, status=201)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
// config/services.php
<?php
return [
'api' => [
'base_url' => env('API_BASE_URL',
env('APP_ENV') === 'local'
? 'https://lightboxapi.com/myproject'
: 'https://api.myapp.com'
),
'timeout' => env('API_TIMEOUT', 30),
],
];
// app/Services/ApiService.php
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Response;
class ApiService
{
protected string $baseUrl;
protected int $timeout;
public function __construct()
{
$this->baseUrl = config('services.api.base_url');
$this->timeout = config('services.api.timeout');
}
/**
* Получить список пользователей
*/
public function getUsers(): array
{
$response = Http::timeout($this->timeout)
->get("{$this->baseUrl}/api/users");
return $response->json();
}
/**
* Получить пользователя по ID
*/
public function getUserById(int $id): array
{
$response = Http::timeout($this->timeout)
->get("{$this->baseUrl}/api/users/{$id}");
return $response->json();
}
/**
* Создать нового пользователя
*/
public function createUser(array $userData): array
{
$response = Http::timeout($this->timeout)
->post("{$this->baseUrl}/api/users", $userData);
return $response->json();
}
/**
* Обновить данные пользователя
*/
public function updateUser(int $id, array $userData): array
{
$response = Http::timeout($this->timeout)
->put("{$this->baseUrl}/api/users/{$id}", $userData);
return $response->json();
}
/**
* Удалить пользователя
*/
public function deleteUser(int $id): bool
{
$response = Http::timeout($this->timeout)
->delete("{$this->baseUrl}/api/users/{$id}");
return $response->successful();
}
}
// app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Services\ApiService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class UserController extends Controller
{
protected ApiService $apiService;
public function __construct(ApiService $apiService)
{
$this->apiService = $apiService;
}
public function index(): JsonResponse
{
try {
$users = $this->apiService->getUsers();
return response()->json($users);
} catch (\Exception $e) {
return response()->json([
'error' => $e->getMessage()
], 500);
}
}
public function store(Request $request): JsonResponse
{
try {
$user = $this->apiService->createUser($request->all());
return response()->json($user, 201);
} catch (\Exception $e) {
return response()->json([
'error' => $e->getMessage()
], 500);
}
}
}
// config/config.go
package config
import "os"
type Config struct {
APIBaseURL string
Timeout int
}
func Load() *Config {
env := os.Getenv("APP_ENV")
defaultURL := "https://api.myapp.com"
if env == "development" {
defaultURL = getEnv("LIGHTBOX_API_URL",
"https://lightboxapi.com/myproject")
}
return &Config{
APIBaseURL: getEnv("API_BASE_URL", defaultURL),
Timeout: 30,
}
}
func getEnv(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}
// models/user.go
package models
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt string `json:"created_at"`
}
type CreateUserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
// services/api_client.go
package services
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"myapp/config"
"myapp/models"
)
type APIClient struct {
baseURL string
httpClient *http.Client
}
func NewAPIClient(cfg *config.Config) *APIClient {
return &APIClient{
baseURL: cfg.APIBaseURL,
httpClient: &http.Client{
Timeout: time.Duration(cfg.Timeout) * time.Second,
},
}
}
func (c *APIClient) GetUsers(ctx context.Context) ([]models.User, error) {
url := fmt.Sprintf("%s/api/users", c.baseURL)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
}
var users []models.User
if err := json.NewDecoder(resp.Body).Decode(&users); err != nil {
return nil, err
}
return users, nil
}
func (c *APIClient) CreateUser(ctx context.Context, userData models.CreateUserRequest) (*models.User, error) {
url := fmt.Sprintf("%s/api/users", c.baseURL)
jsonData, err := json.Marshal(userData)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var user models.User
if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
return nil, err
}
return &user, nil
}
// handlers/user_handler.go
package handlers
import (
"encoding/json"
"net/http"
"myapp/services"
"myapp/models"
)
type UserHandler struct {
apiClient *services.APIClient
}
func NewUserHandler(apiClient *services.APIClient) *UserHandler {
return &UserHandler{apiClient: apiClient}
}
func (h *UserHandler) ListUsers(w http.ResponseWriter, r *http.Request) {
users, err := h.apiClient.GetUsers(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
var userData models.CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&userData); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
user, err := h.apiClient.CreateUser(r.Context(), userData)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
// application.yml
spring:
profiles:
active: ${APP_ENV:development}
---
# Development profile
spring:
config:
activate:
on-profile: development
api:
base-url: ${LIGHTBOX_API_URL:https://lightboxapi.com/myproject}
timeout: 30000
---
# Production profile
spring:
config:
activate:
on-profile: production
api:
base-url: ${API_BASE_URL:https://api.myapp.com}
timeout: 30000
// config/ApiConfig.java
package com.myapp.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import java.time.Duration;
@Configuration
@ConfigurationProperties(prefix = "api")
public class ApiConfig {
private String baseUrl;
private int timeout;
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.rootUri(baseUrl)
.setConnectTimeout(Duration.ofMillis(timeout))
.setReadTimeout(Duration.ofMillis(timeout))
.build();
}
// Getters and setters
public String getBaseUrl() { return baseUrl; }
public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; }
}
// models/User.java
package com.myapp.models;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private String email;
@JsonProperty("created_at")
private String createdAt;
}
// services/ApiService.java
package com.myapp.services;
import com.myapp.models.User;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.util.Arrays;
import java.util.List;
@Service
public class ApiService {
private final RestTemplate restTemplate;
public ApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public List getUsers() {
ResponseEntity response = restTemplate.getForEntity(
"/api/users",
User[].class
);
return Arrays.asList(response.getBody());
}
public User getUserById(Long id) {
return restTemplate.getForObject(
"/api/users/" + id,
User.class
);
}
public User createUser(User user) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity request = new HttpEntity<>(user, headers);
return restTemplate.postForObject(
"/api/users",
request,
User.class
);
}
public void updateUser(Long id, User user) {
restTemplate.put("/api/users/" + id, user);
}
public void deleteUser(Long id) {
restTemplate.delete("/api/users/" + id);
}
}
// controllers/UserController.java
package com.myapp.controllers;
import com.myapp.models.User;
import com.myapp.services.ApiService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
private final ApiService apiService;
public UserController(ApiService apiService) {
this.apiService = apiService;
}
@GetMapping
public ResponseEntity> getUsers() {
try {
List users = apiService.getUsers();
return ResponseEntity.ok(users);
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.build();
}
}
@PostMapping
public ResponseEntity createUser(@RequestBody User user) {
try {
User createdUser = apiService.createUser(user);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(createdUser);
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.build();
}
}
}
# config/initializers/api_config.rb
API_CONFIG = {
development: {
base_url: ENV.fetch('LIGHTBOX_API_URL', 'https://lightboxapi.com/myproject'),
timeout: 30
},
production: {
base_url: ENV.fetch('API_BASE_URL', 'https://api.myapp.com'),
timeout: 30
}
}
API_BASE_URL = API_CONFIG[Rails.env.to_sym][:base_url]
API_TIMEOUT = API_CONFIG[Rails.env.to_sym][:timeout]
# app/services/api_client.rb
require 'httparty'
class ApiClient
include HTTParty
base_uri API_BASE_URL
default_timeout API_TIMEOUT
def initialize
@options = {
headers: {
'Content-Type' => 'application/json',
'Accept' => 'application/json'
}
}
end
def get_users
response = self.class.get('/api/users', @options)
handle_response(response)
end
def get_user(id)
response = self.class.get("/api/users/#{id}", @options)
handle_response(response)
end
def create_user(user_data)
options = @options.merge(body: user_data.to_json)
response = self.class.post('/api/users', options)
handle_response(response)
end
def update_user(id, user_data)
options = @options.merge(body: user_data.to_json)
response = self.class.put("/api/users/#{id}", options)
handle_response(response)
end
def delete_user(id)
response = self.class.delete("/api/users/#{id}", @options)
response.success?
end
private
def handle_response(response)
if response.success?
JSON.parse(response.body)
else
raise "API Error: #{response.code} - #{response.message}"
end
end
end
# app/models/user.rb
class User
attr_accessor :id, :name, :email, :created_at
def initialize(attributes = {})
@id = attributes[:id]
@name = attributes[:name]
@email = attributes[:email]
@created_at = attributes[:created_at]
end
def self.from_json(json)
new(
id: json['id'],
name: json['name'],
email: json['email'],
created_at: json['created_at']
)
end
def to_json(*args)
{
id: @id,
name: @name,
email: @email,
created_at: @created_at
}.to_json(*args)
end
end
# app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :initialize_api_client
def index
begin
users_data = @api_client.get_users
@users = users_data.map { |user| User.from_json(user) }
render json: @users
rescue => e
render json: { error: e.message }, status: :internal_server_error
end
end
def show
begin
user_data = @api_client.get_user(params[:id])
@user = User.from_json(user_data)
render json: @user
rescue => e
render json: { error: e.message }, status: :not_found
end
end
def create
begin
user_data = @api_client.create_user(user_params)
@user = User.from_json(user_data)
render json: @user, status: :created
rescue => e
render json: { error: e.message }, status: :unprocessable_entity
end
end
def update
begin
user_data = @api_client.update_user(params[:id], user_params)
@user = User.from_json(user_data)
render json: @user
rescue => e
render json: { error: e.message }, status: :unprocessable_entity
end
end
def destroy
begin
@api_client.delete_user(params[:id])
head :no_content
rescue => e
render json: { error: e.message }, status: :internal_server_error
end
end
private
def initialize_api_client
@api_client = ApiClient.new
end
def user_params
params.require(:user).permit(:name, :email)
end
end
# config/routes.rb
Rails.application.routes.draw do
resources :users, only: [:index, :show, :create, :update, :destroy]
end
Просто измените переменную окружения для переключения между LightBox и production API
Все примеры используют best practices и готовы для использования в реальных проектах
Используются стандартные библиотеки для каждого языка и фреймворка
Почему LightBox API — лучший выбор для Backend разработки
Возможность | LightBox API | Mockoon | Postman Mock | JSON Server |
---|---|---|---|---|
OpenAPI импорт | За 2 минуты | Ручная настройка | Базовая | |
Облачный хостинг | Из коробки | Локально | Ограничения | Локально |
Динамические ответы | JavaScript | Templating | Статичные | Статичные |
Версионирование API | Несколько версий | |||
Командная работа | Workspace | Платно | ||
Логирование запросов | Детальное | Базовое | ||
Задержки и ошибки | Гибкие настройки | Базовые | ||
CORS настройка | Автоматически | Ручная | Ручная | |
Время настройки | 5 минут | 30-60 минут | 15-30 минут | 45-90 минут |
Стоимость | От 0₽ | Бесплатно | От $49/мес | Бесплатно |
Работает с любым языком и фреймворком
Тысячи Backend разработчиков уже используют LightBox API для параллельной разработки
Начать бесплатно