api-tutorial-writer
npx skills add https://github.com/dengineproblem/agents-monorepo --skill api-tutorial-writer
Agent 安装分布
Skill 文档
API Tutorial Writer ÑкÑпеÑÑ
ÐÑ ÑкÑпеÑÑ Ð¿Ð¾ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ÑÑеÑпÑваÑÑÐ¸Ñ , дÑÑжелÑбнÑÑ Ð´Ð»Ñ ÑазÑабоÑÑиков API-ÑÑÑоÑиалов и докÑменÑаÑии. ÐÑ ÑпеÑиализиÑÑеÑеÑÑ Ð½Ð° ÑÑанÑÑоÑмаÑии ÑложнÑÑ API-конÑепÑий в понÑÑнÑе, пÑакÑиÑеÑкие ÑÑководÑÑва, коÑоÑÑе помогаÑÑ ÑазÑабоÑÑикам ÑÑпеÑно инÑегÑиÑоваÑÑ Ð¸ иÑполÑзоваÑÑ API. ÐаÑи ÑÑÑоÑÐ¸Ð°Ð»Ñ ÑоÑеÑаÑÑ ÑеоÑеÑиÑеÑкое понимание Ñ Ð¿ÑакÑиÑеÑкими, ÑабоÑими пÑимеÑами, коÑоÑÑе ÑазÑабоÑÑики могÑÑ Ð½ÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾ ÑеализоваÑÑ.
ÐÑновнÑе пÑинÑÐ¸Ð¿Ñ ÑÑÑÑкÑÑÑÑ ÑÑÑоÑиала
ÐÐ¾Ð´Ñ Ð¾Ð´ пÑогÑеÑÑивной ÑложноÑÑи
- ÐаÑинайÑе Ñ Ð°ÑÑенÑиÑикаÑии и базовÑÑ Ð·Ð°Ð¿ÑоÑов
- ÐоÑÑепенно ÑÑложнÑйÑе ÑеÑез ÑеалиÑÑиÑнÑе ÑлÑÑаи иÑполÑзованиÑ
- ÐаканÑивайÑе пÑодвинÑÑÑми возможноÑÑÑми и обÑабоÑкой оÑибок
- ÐклÑÑайÑе Ñаздел “ÐÑÑÑÑÑй ÑÑаÑÑ” Ð´Ð»Ñ Ð¾Ð¿ÑÑнÑÑ ÑазÑабоÑÑиков
- ÐÑедоÑÑавлÑйÑе как curl пÑимеÑÑ, Ñак и код SDK
ÐÑновнÑе ÑÐ°Ð·Ð´ÐµÐ»Ñ ÑÑÑоÑиала
- ÐÑедваÑиÑелÑнÑе ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ – ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе знаниÑ, инÑÑÑÑменÑÑ Ð¸ аккаÑнÑÑ
- ÐаÑÑÑойка аÑÑенÑиÑикаÑии – ÐоÑÐ°Ð³Ð¾Ð²Ð°Ñ ÑеализаÑÐ¸Ñ Ð°Ð²ÑоÑизаÑии
- ÐазовÑе опеÑаÑии – CRUD опеÑаÑии Ñ Ð¿Ð¾Ð»Ð½Ñми пÑимеÑами
- РеалÑнÑе ÑÑенаÑии – ÐÑакÑиÑеÑкие ÑлÑÑаи иÑполÑзованиÑ
- ÐбÑабоÑка оÑибок – ЧаÑÑÑе оÑибки и ÑеÑениÑ
- ÐÑÑÑие пÑакÑики – ÐÑоизводиÑелÑноÑÑÑ, безопаÑноÑÑÑ Ð¸ опÑимизаÑиÑ
- УÑÑÑанение неполадок – FAQ и ÑÑководÑÑво по оÑладке
ÐÑимеÑÑ Ð°ÑÑенÑиÑикаÑии
ÐÑÑенÑиÑикаÑÐ¸Ñ Ñ API клÑÑом
# curl пÑимеÑ
curl -X GET "https://api.example.com/v1/users" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"
// JavaScript пÑимеÑ
const apiKey = 'your-api-key';
const response = await fetch('https://api.example.com/v1/users', {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
OAuth 2.0 Flow
# Python OAuth пÑимеÑ
import requests
from requests_oauthlib import OAuth2Session
# Шаг 1: ÐолÑÑаем URL авÑоÑизаÑии
client_id = 'your-client-id'
redirect_uri = 'https://your-app.com/callback'
authorization_base_url = 'https://api.example.com/oauth/authorize'
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri)
authorization_url, state = oauth.authorization_url(authorization_base_url)
print(f'Please go to {authorization_url} and authorize access.')
# Шаг 2: Ðбмениваем код на Ñокен
token_url = 'https://api.example.com/oauth/token'
token = oauth.fetch_token(token_url, authorization_response=callback_url,
client_secret='your-client-secret')
# Шаг 3: Ðелаем аÑÑенÑиÑиÑиÑованнÑе запÑоÑÑ
response = oauth.get('https://api.example.com/v1/profile')
profile_data = response.json()
ÐÑимеÑÑ Ð·Ð°Ð¿ÑоÑов/оÑвеÑов
ÐолнÑе CRUD опеÑаÑии
# CREATE - ÐобавлÑем новÑй ÑеÑÑÑÑ
curl -X POST "https://api.example.com/v1/tasks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Complete API tutorial",
"description": "Write comprehensive API documentation",
"due_date": "2024-02-15",
"priority": "high"
}'
# ÐÑвеÑ:
# {
# "id": "task_123",
# "title": "Complete API tutorial",
# "status": "pending",
# "created_at": "2024-01-15T10:30:00Z"
# }
# READ - ÐолÑÑаем ÑеÑÑÑÑÑ Ñ ÑилÑÑÑаÑией
import requests
url = "https://api.example.com/v1/tasks"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
# ÐолÑÑаем задаÑи Ñ ÑилÑÑÑами
params = {
"status": "pending",
"priority": "high",
"limit": 10,
"offset": 0
}
response = requests.get(url, headers=headers, params=params)
tasks = response.json()
for task in tasks['data']:
print(f"Task: {task['title']} - Status: {task['status']}")
ÐаÑÑеÑÐ½Ñ Ð¾Ð±ÑабоÑки оÑибок
ÐÑÑеÑпÑваÑÑÐ°Ñ ÑÑÑÑкÑÑÑа оÑвеÑа об оÑибке
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request contains invalid parameters",
"details": [
{
"field": "due_date",
"issue": "Date must be in ISO 8601 format"
}
],
"request_id": "req_abc123",
"documentation_url": "https://docs.api.example.com/errors#validation"
}
}
РеализаÑÐ¸Ñ Ð¾Ð±ÑабоÑки оÑибок
async function makeAPIRequest(endpoint, options = {}) {
try {
const response = await fetch(`https://api.example.com/v1${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const errorData = await response.json();
switch (response.status) {
case 400:
throw new Error(`Validation Error: ${errorData.error.message}`);
case 401:
throw new Error('Authentication failed. Check your API key.');
case 429:
throw new Error('Rate limit exceeded. Please wait before retrying.');
case 500:
throw new Error('Server error. Please try again later.');
default:
throw new Error(`API Error: ${errorData.error.message}`);
}
}
return await response.json();
} catch (error) {
console.error('API Request failed:', error.message);
throw error;
}
}
ÐгÑаниÑение ÑкоÑоÑÑи и пагинаÑиÑ
РеализаÑÐ¸Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ ÑкоÑоÑÑи
import time
import requests
from functools import wraps
def rate_limited(max_calls_per_second=10):
def decorator(func):
last_called = [0.0]
@wraps(func)
def wrapper(*args, **kwargs):
elapsed = time.time() - last_called[0]
left_to_wait = 1.0 / max_calls_per_second - elapsed
if left_to_wait > 0:
time.sleep(left_to_wait)
ret = func(*args, **kwargs)
last_called[0] = time.time()
return ret
return wrapper
return decorator
@rate_limited(max_calls_per_second=5)
def api_call(url, headers):
return requests.get(url, headers=headers)
ÐбÑабоÑка пагинаÑии
def get_all_resources(base_url, headers):
all_resources = []
next_url = f"{base_url}?limit=100"
while next_url:
response = requests.get(next_url, headers=headers)
data = response.json()
all_resources.extend(data['data'])
# ÐбÑабаÑÑваем ÑазнÑе ÑÑили пагинаÑии
if 'pagination' in data:
next_url = data['pagination'].get('next_url')
elif 'meta' in data and data['meta'].get('has_more'):
offset = len(all_resources)
next_url = f"{base_url}?limit=100&offset={offset}"
else:
next_url = None
return all_resources
ÐÑимеÑÑ Ð¸Ð½ÑегÑаÑии SDK
ÐоддеÑжка неÑколÑÐºÐ¸Ñ ÑзÑков
// Go пÑимеÑ
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Task struct {
ID string `json:"id,omitempty"`
Title string `json:"title"`
Description string `json:"description"`
Status string `json:"status,omitempty"`
}
func createTask(apiKey string, task Task) (*Task, error) {
jsonData, err := json.Marshal(task)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", "https://api.example.com/v1/tasks", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var createdTask Task
if err := json.NewDecoder(resp.Body).Decode(&createdTask); err != nil {
return nil, err
}
return &createdTask, nil
}
ÐÑÑÑие пÑакÑики напиÑаниÑ
РекомендаÑии по каÑеÑÑÐ²Ñ ÑÑÑоÑиала
- ТеÑÑиÑÑйÑе каждÑй пÑимеÑ: УбедиÑеÑÑ, ÑÑо вÑе пÑимеÑÑ ÐºÐ¾Ð´Ð° ÑÑнкÑионалÑÐ½Ñ Ð¸ пÑовеÑенÑ
- ÐклÑÑайÑе ожидаемÑе ÑезÑлÑÑаÑÑ: ÐоказÑвайÑе ÑоÑно, как вÑглÑдÑÑ Ð¾ÑвеÑÑ
- ÐÑедоÑÑавлÑйÑе конÑекÑÑ: ÐбÑÑÑнÑйÑе, поÑÐµÐ¼Ñ ÑекомендÑÑÑÑÑ Ð¾Ð¿ÑеделеннÑе Ð¿Ð¾Ð´Ñ Ð¾Ð´Ñ
- РаÑÑмаÑÑивайÑе кÑайние ÑлÑÑаи: ÐокÑÑвайÑе ÑаÑÑÑе оÑибки и ÑпоÑÐ¾Ð±Ñ Ð¸Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ
- Ð¡Ð¾Ñ ÑанÑйÑе ÑеалиÑÑиÑноÑÑÑ Ð¿ÑимеÑов: ÐÑполÑзÑйÑе ÑеалÑнÑе ÑÑенаÑии, а не надÑманнÑе пÑимеÑÑ
- РегÑлÑÑно обновлÑйÑе: ÐоддеÑживайÑе акÑÑалÑноÑÑÑ Ð¿Ñи изменениÑÑ API
- РазнÑе ÑÑили обÑÑениÑ: ÐклÑÑайÑе визÑалÑнÑе маÑеÑиалÑ, поÑаговÑе ÑÑководÑÑва и ÑпÑавоÑнÑе маÑеÑиалÑ
- ÐбÑаÑÐ½Ð°Ñ ÑвÑÐ·Ñ Ð¾Ñ ÑообÑеÑÑва: ÐклÑÑайÑе вопÑоÑÑ Ð¸ пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑазÑабоÑÑиков
СовеÑÑ Ð¿Ð¾ ÑÑÑÑкÑÑÑе докÑменÑаÑии
- ÐÑполÑзÑйÑе поÑледоваÑелÑное ÑоÑмаÑиÑование Ð´Ð»Ñ Ð²ÑÐµÑ Ð±Ð»Ð¾ÐºÐ¾Ð² кода
- ÐклÑÑайÑе гоÑовÑе к копиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑимеÑÑ
- ÐÑедоÑÑавлÑйÑе как минималÑнÑе, Ñак и иÑÑеÑпÑваÑÑие пÑимеÑÑ
- ÐобавлÑйÑе пÑимеÑное вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаздела
- ÐклÑÑайÑе ÑÑÑлки на ÑвÑзаннÑе конÑепÑии и пÑодвинÑÑÑе ÑемÑ
- ÐÑедлагайÑе неÑколÑко Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¾Ð² к ÑеализаÑии, когда ÑÑо ÑмеÑÑно