Skip to content

Services

Services are the primary unit of business logic in a Shiva module. A service is a Lua table (class) registered with the container.

What Is a Service?

A service:

  • Holds state (if needed) as instance variables
  • Implements a contract interface
  • Has no global state — everything is injected
  • Is testable in isolation

Creating a Service

bash
shiva make service my-module MyService

This creates server/services/MyService.lua:

lua
local MyService = {}
MyService.__index = MyService

--- Create a new MyService instance
---@param deps table
function MyService.new(deps)
    return setmetatable({
        _db = deps.db,
        _player = deps.player,
    }, MyService)
end

--- Example method
---@param playerId number
---@return table|nil
function MyService:getDataForPlayer(playerId)
    return self._db:first('SELECT * FROM my_table WHERE player_id = ?', playerId)
end

return MyService

Registering a Service

lua
-- server/init.lua
local M = {}

function M.init(container)
    local MyService = require('server.services.MyService')
    container:bind('IMyContract', function()
        return MyService.new({
            db     = container:make('IDatabase'),
            player = container:make('IPlayer'),
        })
    end)
end

return M

Service Rules

  • One responsibility — a service should do one thing
  • No require of other services — take them as constructor arguments
  • Return structured errors — don't error() unless something is truly unexpected
  • No side effects in constructors — construction should be cheap and deterministic

Testing a Service

Since services take their dependencies as arguments, they're easy to test:

lua
-- spec/MyService_spec.lua
local MyService = require('server.services.MyService')

describe('MyService', function()
    it('returns nil for unknown player', function()
        local service = MyService.new({
            db = MockDB.new({ returns = nil }),
            player = MockPlayer.new(),
        })
        assert.is_nil(service:getDataForPlayer(999))
    end)
end)

See Also

Released under the MIT License.