Skip to content

Commit f9e6939

Browse files
markshustclaude
andcommitted
docs: fix API inaccuracies across packages, guides, and tutorials
- pubsub-redis, pubsub-pgsql: use subscription param directly for SSE - validation: validate() returns ValidationErrors, added validateOrFail() - caching: CachePoolInterface → CacheInterface, fix method names - database: ConnectionInterface → QueryBuilderInterface for fluent queries - routing: DisableRoute takes no params, fix attribute namespaces - authentication: AuthManagerInterface → AuthManager - All tutorials: fix Response/Request namespaces, validator API, query builder usage, auth access patterns, event class names Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2a8ab8c commit f9e6939

10 files changed

Lines changed: 238 additions & 173 deletions

File tree

docs/src/content/docs/guides/authentication.md

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ return [
4343

4444
## Using Authentication
4545

46-
Inject the `AuthManagerInterface` to check authentication state:
46+
Inject `AuthManager` to check authentication state:
4747

4848
```php title="app/dashboard/Controller/DashboardController.php"
4949
<?php
@@ -52,17 +52,17 @@ declare(strict_types=1);
5252

5353
namespace App\Dashboard\Controller;
5454

55-
use Marko\Authentication\AuthManagerInterface;
56-
use Marko\Routing\Attribute\Get;
57-
use Marko\Routing\Attribute\Middleware;
55+
use Marko\Authentication\AuthManager;
56+
use Marko\Routing\Attributes\Get;
57+
use Marko\Routing\Attributes\Middleware;
5858
use Marko\Authentication\Middleware\AuthMiddleware;
5959
use Marko\Http\ResponseInterface;
6060
use Marko\Http\JsonResponse;
6161

6262
class DashboardController
6363
{
6464
public function __construct(
65-
private readonly AuthManagerInterface $authManager,
65+
private readonly AuthManager $authManager,
6666
) {}
6767

6868
#[Get('/dashboard')]
@@ -138,37 +138,62 @@ declare(strict_types=1);
138138

139139
namespace App\MyApp\Auth;
140140

141-
use Marko\Authentication\GuardInterface;
141+
use Marko\Authentication\Contracts\GuardInterface;
142142
use Marko\Authentication\AuthenticatableInterface;
143143

144144
class ApiKeyGuard implements GuardInterface
145145
{
146+
public function check(): bool
147+
{
148+
return $this->user() !== null;
149+
}
150+
151+
public function guest(): bool
152+
{
153+
return !$this->check();
154+
}
155+
146156
public function user(): ?AuthenticatableInterface
147157
{
148158
// Look up user by API key from request header
149159
}
150160

151-
public function check(): bool
161+
public function id(): int|string|null
152162
{
153-
return $this->user() !== null;
163+
return $this->user()?->getAuthIdentifier();
154164
}
155165

156166
public function attempt(array $credentials): bool
157167
{
158168
// Validate API key credentials
159169
}
160170

171+
public function login(AuthenticatableInterface $user): void
172+
{
173+
// Store the authenticated user
174+
}
175+
176+
public function loginById(int|string $id): ?AuthenticatableInterface
177+
{
178+
// Find and log in a user by ID
179+
}
180+
161181
public function logout(): void
162182
{
163183
// Invalidate the API key
164184
}
185+
186+
public function getName(): string
187+
{
188+
return 'api-key';
189+
}
165190
}
166191
```
167192

168193
Register it via Preference in your `module.php`:
169194

170195
```php title="module.php"
171-
use Marko\Authentication\GuardInterface;
196+
use Marko\Authentication\Contracts\GuardInterface;
172197
use App\MyApp\Auth\ApiKeyGuard;
173198

174199
return [

docs/src/content/docs/guides/caching.md

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Caching
33
description: Cache data with pluggable backends — file, Redis, or array for testing.
44
---
55

6-
Marko's cache system follows the interface/implementation pattern. Code against `CachePoolInterface`, swap backends by changing a binding.
6+
Marko's cache system follows the interface/implementation pattern. Code against `CacheInterface`, swap backends by changing a binding.
77

88
## Setup
99

@@ -24,49 +24,58 @@ declare(strict_types=1);
2424

2525
namespace App\Blog\Service;
2626

27-
use Marko\Cache\CachePoolInterface;
27+
use Marko\Cache\Contracts\CacheInterface;
2828

2929
class PostService
3030
{
3131
public function __construct(
32-
private readonly CachePoolInterface $cachePool,
32+
private readonly CacheInterface $cache,
3333
) {}
3434

3535
public function getPopularPosts(): array
3636
{
37-
return $this->cachePool->remember('posts.popular', 3600, function () {
38-
// This closure only runs on cache miss
39-
return $this->fetchPopularPostsFromDb();
40-
});
37+
$posts = $this->cache->get('posts.popular');
38+
39+
if ($posts === null) {
40+
$posts = $this->fetchPopularPostsFromDb();
41+
$this->cache->set('posts.popular', $posts, ttl: 3600);
42+
}
43+
44+
return $posts;
4145
}
4246

4347
public function clearPostCache(): void
4448
{
45-
$this->cachePool->forget('posts.popular');
49+
$this->cache->delete('posts.popular');
4650
}
4751
}
4852
```
4953

5054
## Cache Operations
5155

5256
```php
57+
use Marko\Cache\Contracts\CacheInterface;
58+
5359
// Store a value (TTL in seconds)
54-
$this->cache->put('key', $value, ttl: 3600);
60+
$this->cache->set('key', $value, ttl: 3600);
5561

56-
// Retrieve a value
57-
$value = $this->cache->get('key');
62+
// Retrieve a value (with optional default)
63+
$value = $this->cache->get('key', default: 'fallback');
5864

5965
// Check if a key exists
6066
$this->cache->has('key'); // bool
6167

6268
// Remove a key
63-
$this->cache->forget('key');
69+
$this->cache->delete('key');
70+
71+
// Store multiple values
72+
$this->cache->setMultiple(['key1' => $val1, 'key2' => $val2], ttl: 3600);
6473

65-
// Get or compute (cache-aside pattern)
66-
$value = $this->cache->remember('key', 3600, fn () => expensiveComputation());
74+
// Retrieve multiple values
75+
$values = $this->cache->getMultiple(['key1', 'key2']);
6776

6877
// Clear all cache
69-
$this->cache->flush();
78+
$this->cache->clear();
7079
```
7180

7281
## Switching Backends
@@ -78,12 +87,12 @@ Change from file cache to Redis by updating your `module.php`:
7887

7988
declare(strict_types=1);
8089

81-
use Marko\Cache\CachePoolInterface;
82-
use Marko\Cache\Redis\RedisCachePool;
90+
use Marko\Cache\Contracts\CacheInterface;
91+
use Marko\Cache\Redis\Driver\RedisCacheDriver;
8392

8493
return [
8594
'bindings' => [
86-
CachePoolInterface::class => RedisCachePool::class,
95+
CacheInterface::class => RedisCacheDriver::class,
8796
],
8897
];
8998
```

docs/src/content/docs/guides/database.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ marko db:status
9696

9797
## Querying
9898

99-
Use the `ConnectionInterface` for database queries:
99+
### Query Builder
100+
101+
Use `QueryBuilderInterface` for fluent query building:
100102

101103
```php title="app/blog/Repository/PostRepository.php"
102104
<?php
@@ -105,33 +107,33 @@ declare(strict_types=1);
105107

106108
namespace App\Blog\Repository;
107109

108-
use Marko\Database\ConnectionInterface;
110+
use Marko\Database\Query\QueryBuilderInterface;
109111
use DateTimeImmutable;
110112

111113
class PostRepository
112114
{
113115
public function __construct(
114-
private readonly ConnectionInterface $connection,
116+
private readonly QueryBuilderInterface $queryBuilder,
115117
) {}
116118

117119
public function findById(int $id): ?array
118120
{
119-
return $this->connection->table('posts')
120-
->where('id', $id)
121+
return $this->queryBuilder->table('posts')
122+
->where('id', '=', $id)
121123
->first();
122124
}
123125

124126
public function findPublished(): array
125127
{
126-
return $this->connection->table('posts')
127-
->where('published', true)
128-
->orderBy('created_at', 'desc')
128+
return $this->queryBuilder->table('posts')
129+
->where('published', '=', true)
130+
->orderBy('created_at', 'DESC')
129131
->get();
130132
}
131133

132134
public function create(string $title, string $body): int
133135
{
134-
return $this->connection->table('posts')->insert([
136+
return $this->queryBuilder->table('posts')->insert([
135137
'title' => $title,
136138
'body' => $body,
137139
'published' => false,
@@ -152,19 +154,19 @@ declare(strict_types=1);
152154

153155
namespace App\Blog\Database\Seeder;
154156

155-
use Marko\Database\ConnectionInterface;
157+
use Marko\Database\Query\QueryBuilderInterface;
156158
use Marko\Database\SeederInterface;
157159
use DateTimeImmutable;
158160

159161
class PostSeeder implements SeederInterface
160162
{
161163
public function __construct(
162-
private readonly ConnectionInterface $connection,
164+
private readonly QueryBuilderInterface $queryBuilder,
163165
) {}
164166

165167
public function run(): void
166168
{
167-
$this->connection->table('posts')->insert([
169+
$this->queryBuilder->table('posts')->insert([
168170
'title' => 'Hello World',
169171
'body' => 'Welcome to Marko.',
170172
'published' => true,

docs/src/content/docs/guides/routing.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ declare(strict_types=1);
1414

1515
namespace App\Blog\Controller;
1616

17-
use Marko\Routing\Attribute\Get;
18-
use Marko\Routing\Attribute\Post;
19-
use Marko\Routing\Attribute\Delete;
17+
use Marko\Routing\Attributes\Get;
18+
use Marko\Routing\Attributes\Post;
19+
use Marko\Routing\Attributes\Delete;
2020
use Marko\Http\ResponseInterface;
2121
use Marko\Http\JsonResponse;
2222

@@ -75,8 +75,8 @@ public function show(int $userId, int $postId): ResponseInterface
7575
Apply middleware to routes using the `#[Middleware]` attribute:
7676

7777
```php
78-
use Marko\Routing\Attribute\Get;
79-
use Marko\Routing\Attribute\Middleware;
78+
use Marko\Routing\Attributes\Get;
79+
use Marko\Routing\Attributes\Middleware;
8080
use Marko\Authentication\Middleware\AuthMiddleware;
8181

8282
class AdminController
@@ -112,14 +112,16 @@ Higher-priority modules can override routes from lower-priority modules. If `ven
112112

113113
## Disabling Routes
114114

115-
To remove a vendor route without replacing it, use the `#[DisableRoute]` attribute:
115+
To remove a vendor route without replacing it, use the `#[DisableRoute]` attribute. Place it on a method that also has the route attribute you want to disable --- `#[DisableRoute]` takes no parameters and simply disables the route defined by the preceding routing attribute:
116116

117117
```php
118-
use Marko\Routing\Attribute\DisableRoute;
118+
use Marko\Routing\Attributes\Get;
119+
use Marko\Routing\Attributes\DisableRoute;
119120

120121
class BlogRouteOverrides
121122
{
122-
#[DisableRoute(method: 'GET', path: '/blog/rss')]
123+
#[Get('/blog/rss')]
124+
#[DisableRoute]
123125
public function disableRss(): void {}
124126
}
125127
```
@@ -137,7 +139,7 @@ namespace App\MyApp\Middleware;
137139

138140
use Marko\Http\RequestInterface;
139141
use Marko\Http\ResponseInterface;
140-
use Marko\Routing\MiddlewareInterface;
142+
use Marko\Routing\Middleware\MiddlewareInterface;
141143

142144
class RateLimitMiddleware implements MiddlewareInterface
143145
{

0 commit comments

Comments
 (0)