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 8080Endpoints
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/startResponse:
{
"success": true,
"message": "Service started successfully"
}POST /api/shurikens//stop
Stop a shuriken.
Request:
curl -X POST http://localhost:8080/api/shurikens/example-service/stopResponse:
{
"success": true,
"message": "Service stopped successfully"
}POST /api/shurikens//restart
Restart a shuriken.
Request:
curl -X POST http://localhost:8080/api/shurikens/example-service/restartPOST /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-servicePOST /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 StateMapExample 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