Logo
Reference

API Reference

HTTP and GraphQL API reference for Ninja service management.

HTTP REST API

Starting the API Server

# Via CLI
shurikenctl api --port 8080

# Via code
cargo run -p HTTP -- --port 8080

Endpoints

GET /api/shurikens

List all installed shurikens.

Response:

{
  "shurikens": [
    "example-service",
    "webserver",
    "database"
  ]
}

GET /api/shurikens/states

Get state information for all shurikens.

Response:

{
  "example-service": "Running",
  "webserver": "Idle",
  "database": "Running"
}

GET /api/shurikens/

Get detailed information about a shuriken.

Response:

{
  "name": "example-service",
  "state": "Running",
  "manifest": {
    "name": "example-service",
    "id": "com.example.service",
    "version": "1.0.0",
    "type": "daemon"
  }
}

POST /api/shurikens/
/start

Start a shuriken.

Request:

curl -X POST http://localhost:8080/api/shurikens/example-service/start

Response:

{
  "success": true,
  "message": "Service started successfully"
}

POST /api/shurikens/
/stop

Stop a shuriken.

Request:

curl -X POST http://localhost:8080/api/shurikens/example-service/stop

Response:

{
  "success": true,
  "message": "Service stopped successfully"
}

POST /api/shurikens/
/restart

Restart a shuriken.

Request:

curl -X POST http://localhost:8080/api/shurikens/example-service/restart

POST /api/shurikens/
/configure

Generate configuration for a shuriken.

Request:

curl -X POST http://localhost:8080/api/shurikens/example-service/configure \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "port": 8080,
      "host": "localhost"
    }
  }'

Response:

{
  "success": true,
  "message": "Configuration generated"
}

POST /api/install

Install a shuriken package.

Request:

curl -X POST http://localhost:8080/api/install \
  -F "file=@/path/to/package.shuriken"

POST /api/remove/

Remove a shuriken.

Request:

curl -X POST http://localhost:8080/api/remove/example-service

POST /api/dsl/execute

Execute DSL commands.

Request:

curl -X POST http://localhost:8080/api/dsl/execute \
  -H "Content-Type: application/json" \
  -d '{
    "command": "start example-service"
  }'

Response:

{
  "success": true,
  "output": "Service started successfully"
}

GraphQL API

Access GraphQL at /graphql.

Schema

type Query {
  shurikens: [String!]!
  shuriken(name: String!): Shuriken
  states: StateMap!
}

type Mutation {
  startShuriken(name: String!): OperationResult!
  stopShuriken(name: String!): OperationResult!
  restartShuriken(name: String!): OperationResult!
  configureShuriken(name: String!, options: JSON): OperationResult!
  installShuriken(path: String!): OperationResult!
  removeShuriken(name: String!): OperationResult!
}

type Shuriken {
  name: String!
  state: State!
  manifest: Manifest!
}

type Manifest {
  name: String!
  id: String!
  version: String!
  type: String!
}

enum State {
  RUNNING
  IDLE
}

type OperationResult {
  success: Boolean!
  message: String
  error: String
}

scalar JSON
scalar StateMap

Example Queries

List shurikens:

query {
  shurikens
}

Get shuriken info:

query {
  shuriken(name: "example-service") {
    name
    state
    manifest {
      version
      type
    }
  }
}

Get all states:

query {
  states
}

Example Mutations

Start shuriken:

mutation {
  startShuriken(name: "example-service") {
    success
    message
  }
}

Configure shuriken:

mutation {
  configureShuriken(
    name: "webserver"
    options: {
      port: 8080
      host: "localhost"
    }
  ) {
    success
    message
  }
}

Error Responses

404 Not Found

{
  "success": false,
  "error": "Shuriken not found"
}

409 Conflict

{
  "success": false,
  "error": "Service already running"
}

500 Internal Server Error

{
  "success": false,
  "error": "Internal server error: details"
}

Authentication

Currently, the API does not require authentication. For production use, implement authentication middleware.

CORS

CORS is enabled for all origins in development. Configure appropriately for production.

Rate Limiting

No rate limiting is currently implemented. Consider adding rate limiting for production deployments.

WebSocket Support

Real-time updates via WebSocket at /ws:

const ws = new WebSocket('ws://localhost:8080/ws');

ws.onmessage = (event) => {
  const update = JSON.parse(event.data);
  console.log('State update:', update);
};

Update format:

{
  "type": "state_change",
  "shuriken": "example-service",
  "old_state": "Idle",
  "new_state": "Running"
}

Client Libraries

JavaScript/TypeScript

class NinjaClient {
  constructor(private baseUrl: string) {}

  async list(): Promise<string[]> {
    const res = await fetch(`${this.baseUrl}/api/shurikens`);
    return res.json();
  }

  async start(name: string): Promise<void> {
    await fetch(`${this.baseUrl}/api/shurikens/${name}/start`, {
      method: 'POST'
    });
  }

  async stop(name: string): Promise<void> {
    await fetch(`${this.baseUrl}/api/shurikens/${name}/stop`, {
      method: 'POST'
    });
  }
}

Python

import requests

class NinjaClient:
    def __init__(self, base_url):
        self.base_url = base_url
    
    def list(self):
        return requests.get(f"{self.base_url}/api/shurikens").json()
    
    def start(self, name):
        return requests.post(f"{self.base_url}/api/shurikens/{name}/start")
    
    def stop(self, name):
        return requests.post(f"{self.base_url}/api/shurikens/{name}/stop")

See also: CLI Reference, Developer API Guide

On this page