Files
tingz/API.md
2025-10-14 22:12:12 +03:00

7.0 KiB

API with cURL

Complete guide to tingz API with cURL.

Assumptions

  • Running deployer service on http://localhost:8080
  • Admin token (set in .env.development as ADMIN_TOKEN) set to devadmintoken
  • API version is v1

Step 1: Create a User (Admin Only)

First, an admin needs to create a user account to get a deployment token.

curl -X POST "http://localhost:8080/api/v1/auth" \
  -H "Authorization: Bearer devadmintoken" \
  -H "Content-Type: application/json" \
  -d '{"username":"alice"}'

Success Response:

{
  "status": "ok",
  "token": "82lz0BVOWtV4uVj9DBZBuKMeyVDwidL2"
}

Important: Save this token! You'll need it for all deployments for that user.

Username Requirements

  • Lowercase letters, numbers, hyphens, underscores only
  • 1-64 characters
  • Must start and end with alphanumeric character
  • Pattern: ^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$

Step 2: Prepare Your Static Site

Package your static site as a .tar.gz file with files at the root level.

Correct Way (Files at Root)

cd /path/to/your/site
tar -czf ../site.tar.gz .

This creates a tarball where index.html is at the root, not nested in a directory.

What NOT to Do

# DON'T: This creates site/index.html (nested)
tar -czf site.tar.gz site/

# DON'T: This creates /path/to/your/site/index.html (nested)
tar -czf site.tar.gz /path/to/your/site

Verify Your Tarball

tar -tzf site.tar.gz | head -5

Expected output:

index.html
css/
css/style.css
js/
js/app.js

NOT:

site/index.html    ← Wrong! Nested directory
site/css/style.css

Step 3: Deploy Your Site

Use your user token to deploy the site.

curl -X POST "http://localhost:8080/api/v1/deploy" \
  -H "Authorization: Bearer YOUR_USER_TOKEN" \
  -F "project=myproject" \
  -F "file=@site.tar.gz"

Success Response:

{
  "status": "ok",
  "project": "myproject",
  "username": "alice",
  "url": "https://docs.yigid.dev/alice/myproject/",
  "release": "20251014T180806"
}

Project Name Requirements

  • Same rules as username
  • Lowercase, alphanumeric, hyphens, underscores
  • 1-64 characters
  • Pattern: ^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$

Important Notes

  • The @ prefix is required for file uploads: -F "file=@site.tar.gz"
  • Max upload size: 100MB (default, configurable)
  • Files are deployed to: /var/www/docs/{username}/{project}/
  • Each deployment creates a new release in /var/www/deploys/{username}/{project}/{release_id}/
  • The deploy directory is an atomic symlink to the latest release
  • Old releases are kept (5 by default) for rollback

Step 4: Verify Deployment

ls -la docs/alice/myproject

Output:

lrwxr-xr-x  1 deployer deployer  47 Oct 14 21:08 myproject -> /var/www/deploys/alice/myproject/20251014T180806

Check the Files

ls -la deploys/alice/myproject/20251014T180806/

Access Your Site

curl http://localhost:8080/alice/myproject/
# or
curl https://docs.yigid.dev/alice/myproject/

Complete Workflow Example

# 1. Set your admin token
export ADMIN_TOKEN="devadmintoken"

# 2. Create user and capture token
USER_TOKEN=$(curl -s -X POST "http://localhost:8080/api/v1/auth" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"username":"alice"}' | jq -r '.token')

echo "User token: ${USER_TOKEN}"

# 3. Create test site
mkdir -p my-site
cat > my-site/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>My Site</title></head>
<body><h1>Hello, World!</h1></body>
</html>
EOF

# 4. Package site
tar -czf site.tar.gz -C my-site .

# 5. Deploy
curl -s -X POST "http://localhost:8080/api/v1/deploy" \
  -H "Authorization: Bearer ${USER_TOKEN}" \
  -F "project=mysite" \
  -F "file=@site.tar.gz" | jq

# 6. Verify
curl http://localhost:8080/alice/mysite/

Health Check

Test if the service is running:

curl http://localhost:8080/api/v1/status

Expected response:

{
  "status": "ok"
}

Error Responses

Invalid Token

{
  "status": "error",
  "error": "unauthorized"
}

Invalid Project Name

{
  "status": "error",
  "error": "invalid project name format"
}

Missing File

{
  "status": "error",
  "error": "missing or invalid file"
}

Upload Too Large

{
  "status": "error",
  "error": "request body too large"
}

Path Traversal in Tarball

{
  "status": "error",
  "error": "failed to extract tarball: path contains '..' component which is not allowed: ../../etc/passwd"
}

User Management (Admin Only)

Reroll User Token

Create a new token for an existing user (invalidates old token):

curl -X POST "http://localhost:8080/api/v1/auth" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"username":"alice"}'

Delete User (Keep Files)

curl -X DELETE "http://localhost:8080/api/v1/auth" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","files":"persist"}'

Delete User and All Files

curl -X DELETE "http://localhost:8080/api/v1/auth" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","files":"delete"}'

CI/CD Integration

GitHub Actions

name: Deploy Documentation
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Build site
        run: |
          # Your build steps here
          npm run build
      
      - name: Package and deploy
        env:
          DEPLOYER_TOKEN: ${{ secrets.DEPLOYER_TOKEN }}
        run: |
          tar -czf site.tar.gz -C dist .
          curl -f -X POST "https://deployer.example.com/api/v1/deploy" \
            -H "Authorization: Bearer ${DEPLOYER_TOKEN}" \
            -F "project=docs" \
            -F "file=@site.tar.gz"

GitLab CI

deploy:
  stage: deploy
  only:
    - main
  script:
    - tar -czf site.tar.gz -C public .
    - |
      curl -f -X POST "https://deployer.example.com/api/v1/deploy" \
        -H "Authorization: Bearer ${DEPLOYER_TOKEN}" \
        -F "project=docs" \
        -F "file=@site.tar.gz"
  variables:
    DEPLOYER_TOKEN: $DEPLOYER_TOKEN

Tips & Best Practices

  1. Always use @ for file uploads: -F "file=@your-file.tar.gz"

  2. Verify tarball contents before deploying:

    tar -tzf site.tar.gz | head -20
    
  3. Use -f flag in CI/CD to fail on HTTP errors:

    curl -f -X POST ...
    
  4. Pretty-print JSON responses with jq:

    curl ... | jq
    
  5. Avoid macOS resource forks in tarballs:

    COPYFILE_DISABLE=1 tar -czf site.tar.gz -C dist .
    
  6. Check release history:

    ls -lt deploys/alice/myproject/
    
  7. Atomic deployments: The symlink swap is atomic, so no downtime during deployment

  8. Release retention: Old releases are kept (5 by default) for manual rollback if needed