Write documentation on how to implement additional commands on the server #232
@@ -0,0 +1,29 @@
|
|||||||
|
# Commands
|
||||||
|
Commands are the primary extension point of the server.
|
||||||
|
Every client-facing operation e.g. checking a username, sending a chat message, joining a lobby is implemented as a command.
|
||||||
|
Each command consists of four classes: a **Parser**, a **Request**, a **Handler**, and a **Response**.
|
||||||
|
|
||||||
|
The infrastructure for routing and dispatching commands lives in the `network/` layer and is intentionally kept generic.
|
||||||
|
The concrete implementations for each command live in `app/commands/` and are wired together at startup in `ServerApp`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Contents
|
||||||
|
### Guides
|
||||||
|
*Link to guides*
|
||||||
|
|
||||||
|
### Reference
|
||||||
|
*Link to technical deep dives*
|
||||||
|
|
||||||
|
## Key Concepts
|
||||||
|
**Each command is self-contained.**
|
||||||
|
A command's Parser, Request, Handler, and Response all live in the same package under `app/commands/<name>/`.
|
||||||
|
This keeps related code co-located and makes it easy to reason about a single command without navigating across multiple directories.
|
||||||
|
|
||||||
|
**The `network/` layer knows nothing about specific commands.**
|
||||||
|
`CommandParser` and `CommandHandler` are generic interfaces. The `CommandParserDispatcher` and `CommandRouter` operate on those interfaces.
|
||||||
|
Adding a new command **never** requires modifying infrastructure code.
|
||||||
|
|
||||||
|
**Registration happens at the composition root.**
|
||||||
|
All commands are wired in `ServerApp` by calling `parserDispatcher.register(...)` and `commandRouter.register(...)`.
|
||||||
|
This keeps the wiring explicit and compiler-checked.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@startuml
|
||||||
|
skinparam backgroundColor transparent
|
||||||
|
|
||||||
|
package "network/ (infrastructure)" {
|
||||||
|
class PrimitiveRequest <<record>>
|
||||||
|
interface CommandParser<T extends Request>
|
||||||
|
interface CommandHandler<T extends Request>
|
||||||
|
class CommandParserDispatcher
|
||||||
|
class CommandRouter
|
||||||
|
abstract class Request
|
||||||
|
abstract class Response
|
||||||
|
|
||||||
|
PrimitiveRequest --> CommandParserDispatcher : routes
|
||||||
|
PrimitiveRequest ..> CommandParser : parsed by
|
||||||
|
CommandParserDispatcher --> CommandParser : routes to
|
||||||
|
CommandParser --> Request : parses to
|
||||||
|
Request --> CommandRouter : routes
|
||||||
|
CommandRouter --> CommandHandler : routes to
|
||||||
|
Request ..> CommandHandler : executed by
|
||||||
|
CommandHandler --> Response : creates
|
||||||
|
}
|
||||||
|
|
||||||
|
package "app/commands/<name>/ (per command)" {
|
||||||
|
class ExampleParser implements CommandParser
|
||||||
|
class ExampleRequest extends Request
|
||||||
|
class ExampleHandler implements CommandHandler
|
||||||
|
class ExampleResponse extends Response
|
||||||
|
|
||||||
|
ExampleParser --> ExampleRequest : parses to
|
||||||
|
ExampleRequest --> ExampleHandler : executed by
|
||||||
|
ExampleHandler --> ExampleResponse : produces
|
||||||
|
}
|
||||||
|
@enduml
|
||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user