Skip to content

Technical — API Connect ​

RAGA's HTTP proxy service, built on Node.js + Express. Accepts API connection and endpoint configuration via the request body, handles authentication (Basic, Bearer, or JWT auto-login), then forwards the request to the external API and returns its response. Used by the Raga Engine (Text-to-API) in api-tarantula to call external APIs configured by the user without storing credentials on the server.

Note: this service is stateless — no API configuration is stored. All credentials and endpoint details are sent by the caller inside the request body every time.

Repository ​

KeyValue
Git Remotehttps://git.tlab.co.id/tarantula/service/api-connect.git
Active Branchmain
bash
git clone https://git.tlab.co.id/tarantula/service/api-connect.git
cd api-connect

Tech Stack ​

LayerTechnology
RuntimeNode.js 18
FrameworkExpress 4
HTTP Clientaxios
API Docsswagger-ui-express + swagger-jsdoc (inline JSDoc)
Dev Runnernodemon
ContainerizationDocker (node:18)

Folder Structure ​

api-connect/
├── index.js             # Express app + all proxy & auth logic
├── package.json
├── Dockerfile
├── Dockerfile.stag
└── docker-compose.dev.yml

Environment Variables ​

This service does not use environment variables. All configuration (host, auth, endpoint) is sent per request by the caller inside the request body.

Endpoints ​

MethodPathDescription
GET/healthService health check
POST/proxyForward a request to an external API
GET/api-docsSwagger UI (OpenAPI 3.0)

POST /proxy ​

Forwards an HTTP request to an external API with automatic authentication handling.

Request body:

json
{
  "connection": {
    "host": "https://api.example.com",
    "name": "Connection name (optional, for logging)",
    "auth": { },
    "endpoint": {
      "path": "/v1/data",
      "method": "get",
      "params": [
        { "key": "search", "value": "query" }
      ],
      "body": { }
    },
    "headers": {
      "X-Custom-Header": "value"
    }
  }
}

Response: The target API's response is passed through directly to the caller.

400 Response: If connection, host, or endpoint is missing from the body.

500 Response: If the proxy request fails or the JWT login step fails.

Operational note: index.js currently writes the URL, method, body/params, and the full headers (including the resolved Authorization header for Basic/Bearer/JWT) to console.log for every proxied request. Since auth is sent in full by the caller and never persisted, any external API credentials used through this service end up logged to the container's console as long as this log line is active — make sure logs aren't stored anywhere broadly accessible.

Authentication Modes (auth) ​

Basic Auth ​

json
{
  "auth": {
    "type": "basic",
    "user": "username",
    "password": "password"
  }
}

Header sent to the target API: Authorization: Basic <base64(user:password)>

Bearer Token ​

json
{
  "auth": {
    "type": "bearer",
    "token": "your_access_token"
  }
}

Header sent to the target API: Authorization: Bearer <token>

JWT (Auto-login) ​

json
{
  "auth": {
    "type": "jwt",
    "user": "username",
    "password": "password",
    "loginPath": "/auth/login"
  }
}

The service first does a POST {host}{loginPath} with { user, password }, extracts token from the response, then uses Bearer <token> for the main request.

Request Flow ​

Behavior per HTTP Method ​

MethodBody sent asAutomatic Content-Type
GET, HEADQuery params (params)—
POST, PUT, PATCH, DELETERequest body (data)application/x-www-form-urlencoded

If endpoint.body or connection.body is present, its value is used as the request body. Custom headers from connection.headers are always merged into every request.

Example Requests ​

GET with Basic Auth ​

bash
curl -X POST http://localhost:3000/proxy \
  -H "Content-Type: application/json" \
  -d '{
    "connection": {
      "host": "https://api.example.com",
      "auth": {
        "type": "basic",
        "user": "admin",
        "password": "secret"
      },
      "endpoint": {
        "path": "/v1/users",
        "method": "get",
        "params": [
          { "key": "page", "value": "1" }
        ]
      }
    }
  }'

POST with JWT Auto-login ​

bash
curl -X POST http://localhost:3000/proxy \
  -H "Content-Type: application/json" \
  -d '{
    "connection": {
      "host": "https://api.internal.co.id",
      "auth": {
        "type": "jwt",
        "user": "service_account",
        "password": "pass123",
        "loginPath": "/api/auth/login"
      },
      "endpoint": {
        "path": "/api/v2/reports",
        "method": "post",
        "body": { "from": "2026-01-01", "to": "2026-06-30" }
      }
    }
  }'

GET /health ​

json
{ "status": "OK", "timestamp": "2026-06-30T10:00:00.000Z" }

Build & Run ​

bash
# Install dependencies
npm install

# Run development (nodemon)
npm start

# Run production (node directly)
npm run start_stag

# Docker Compose (dev)
docker compose -f docker-compose.dev.yml up --build

# Standalone Docker build & run
docker build -t api-connect .
docker run -p 3000:3000 api-connect