operations skill
RESTful uç noktaları için API operasyon yaşam döngüsünü, güvenlik ifadelerini, doğrulama gruplarını ve parametre düzeyindeki kısıtlamaları yapılandırır.
- GitHub yıldızları
- 29
- Dosyalar
- 1
- Son commit
- 22 Eki 2026
- Lisans
- —
- İzin verilen araçlar
- —
operations skill ne işe yarar?
operations bir agent skill'dir. RESTful uç noktaları için API operasyon yaşam döngüsünü, güvenlik ifadelerini, doğrulama gruplarını ve parametre düzeyindeki kısıtlamaları yapılandırır.
Özet, skill'in SKILL.md dosyasından oluşturuldu.
operations skilli hakkında
Bu SKILL, API Platform kullanan geliştiricilerin RESTful uç noktaları için API operasyon yaşam döngülerini, güvenliği ve doğrulamayı yapılandırmasına olanak tanır. Bir isteğin okuma ve yazma aşamaları üzerinde hassas kontrol sağlar; böylece kullanıcılar dosya indirme veya özel upsert mantığı gibi görevleri yönetmek için sağlayıcıları (providers) ve işlemcileri (processors) değiştirebilirler. Geliştiriciler, farklı HTTP yöntemleri için okuma ve yazma bayraklarını açıkça ayarlayarak CQRS ayrımını yönetmek için bu özelliği kullanabilirler.
Yaşam döngüsü yönetiminin ötesinde bu SKILL, rol tabanlı veya nesne tabanlı erişim kontrolü için Symfony ExpressionLanguage kullanarak uç noktaları güvenli hale getirecek araçlar sunar. Ayrıca sorgu ve başlık (header) parametreleri için parametre düzeyinde güvenlik sağlar. Veri bütünlüğü için, oluşturma ve güncelleme kısıtlamalarını birbirinden ayırmak üzere doğrulama gruplarını ve denormalizasyon hataları için hata toplama özelliğini destekler. Ayrıca belirli başlıklar aracılığıyla uç nokta kullanımdan kaldırma (deprecation) süreçlerini yönetir ve JSON merge-patch senaryolarında iç içe geçmiş PATCH isteklerinin işlenmesi için rehberlik sağlar.
Bir agent bununla neler yapabilir
- 1Uç nokta erişimini role göre sınırlandırınBir yapay zeka ajanı, bir POST operasyonunu yalnızca yönetici yetkisine sahip kullanıcıların çalıştırabileceği şekilde yapılandırabilir.
- 2Farklı doğrulama kuralları uygulayınBir geliştirici, bir kullanıcı kaynağını oluştururken ve güncellerken kullanılacak belirli doğrulama gruplarını ajana talimat olarak verebilir.
- 3Belirli sorgu parametrelerini güvenli hale getirinBelirli bir sorgu parametresinin, sağlayıcı (provider) çalışmadan önce bir güvenlik ifadesine karşı doğrulanmasını talep edebilirsiniz.
- 4API kullanımdan kaldırma bildirimlerini iletinBir ajan, istemcileri yaklaşan değişiklikler hakkında bilgilendirmek için mevcut bir kaynağa kullanımdan kaldırma nedenleri ve gün batımı (sunset) tarihleri ekleyebilir.
- 5Detaylı hata raporlamayı etkinleştirinBir geliştirici, API'nin ilk hatada durmak yerine tüm hatalı alan hatalarını tek seferde döndürecek şekilde yapılandırılmasını sağlayabilir.
Skill'in SKILL.md dosyasından yazılmıştır. Her kullanım durumu oradaki bir alıntı ile kontrol edilir.
operations skill nasıl kurulur
Her komut, skill klasörünü istemcinin skills dizinine kopyalar. Yüklemek için istemciyi yeniden başlatın veya yeni bir oturum başlatın.operations skill'ini Eklenti uygulamasına kur
/plugin marketplace add api-platform/skillset /plugin install api-platform@api-platform-skillset
operations skill'ini Claude Code uygulamasına kur
~/.claude/skills/operations/SKILL.md
$ npx degit api-platform/skillset/skills/operations ~/.claude/skills/operationsoperations skill'ini Claude Code (project) uygulamasına kur
.claude/skills/operations/SKILL.md
$ npx degit api-platform/skillset/skills/operations .claude/skills/operationsoperations skill'ini Codex uygulamasına kur
~/.agents/skills/operations/SKILL.md
$ npx degit api-platform/skillset/skills/operations ~/.agents/skills/operationsoperations skill'ini Gemini CLI uygulamasına kur
~/.gemini/skills/operations/SKILL.md
$ npx degit api-platform/skillset/skills/operations ~/.gemini/skills/operationsoperations skill'ini Claude.ai uygulamasına kur
npx degit api-platform/skillset/skills/operations operations && zip -r operations.zip operations # claude.ai → Customize → Skills → + → Create skill → Upload a skill → operations.zip
SKILL.md
GitHub'da görüntüleOperations: Security, Validation & Lifecycle
Operation-level configuration that sits between the resource shape (see api-resource) and the read/write logic (see state-provider / state-processor).
Read & write phases (the provider/processor lifecycle)
Every operation runs two phases, each toggled by a boolean flag:
| Phase | Flag | Runs | Maps to (CQRS) |
|---|---|---|---|
| Read | read |
a provider fetches the data | Query |
| Write | write |
a processor persists / acts on the data | Command |
A full request is read → deserialize → validate → write → serialize. The provider
supplies the object the rest of the chain operates on; the processor performs the
side effect (persist, delete, send mail, build a file). This is API Platform's CQRS
split: GET-style reads go through a provider, state changes go through a
processor.
The flags default from the request, not the verb
You leave read/write unset and API Platform resolves them at runtime from the
HTTP request (see MainController / WriteListener in core):
writedefaults to "the method is not safe" —falseforGET/HEAD,trueforPOST,PUT,PATCH,DELETE.readdefaults to "the operation has URI variables, or the method is safe" — so item operations (which carry{id}) and allGETs read, but a collectionPOST(no URI variables, unsafe) does not.
| Operation | read |
write |
|---|---|---|
Get (item) |
true (has {id}) |
false |
GetCollection |
true (safe) |
false |
Post (collection) |
false (no URI vars, unsafe) |
true |
Put, Patch (item) |
true (has {id}) |
true |
Delete (item) |
true (has {id}) |
true |
So a Get skips the processor by default, and a collection Post runs a processor
without a provider. Override either flag to decouple the phase from this default:
// Run a processor on a GET (file download, report generation, counter bump):
new Get(
uriTemplate: '/orders/{id}/download',
write: true, // turn the write phase ON — processor now fires
processor: OrderDownloadProcessor::class,
)
// Skip the built-in fetch on an item write (upsert: processor handles a missing row):
new Put(
read: false, // no provider runs; $data comes from deserialization only
processor: UpsertProcessor::class,
)
write: true is the common case: a Get whose write defaults to false would
never invoke its processor — flipping the flag is what enables it. Conversely
read: false stops the built-in provider on an item operation from a needless fetch.
Securing operations
The security attribute takes a Symfony ExpressionLanguage string evaluated
before the operation runs. Available variables: user, object (item operations),
request parameters when explicitly exposed.
Role-based
#[ApiResource(
operations: [
new GetCollection(),
new Post(security: "is_granted('ROLE_ADMIN')"),
]
)]
class Invoice {}
Object-based (item operations)
object is the fetched resource — use it for ownership checks on Get, Put,
Patch, Delete:
new Get(security: "object.getOwner() == user")
new Patch(security: "object.getOwner() == user or is_granted('ROLE_ADMIN')")
securityPostDenormalize runs after the request body is applied — use it when the
decision depends on incoming values (e.g. preventing privilege escalation on PATCH).
Parameter-based
Each parameter carries its own security expression, where the parameter name
becomes a variable bound to the submitted value. Declare them in parameters as
QueryParameter or HeaderParameter:
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\HeaderParameter;
use ApiPlatform\Metadata\QueryParameter;
use Symfony\Component\TypeInfo\Type\BuiltinType;
use Symfony\Component\TypeInfo\TypeIdentifier;
#[GetCollection(
parameters: [
'name' => new QueryParameter(security: 'is_granted("ROLE_ADMIN")'),
'auth' => new HeaderParameter(security: '"secured" == auth', nativeType: new BuiltinType(TypeIdentifier::STRING)),
'secret' => new QueryParameter(security: '"secured" == secret', nativeType: new BuiltinType(TypeIdentifier::STRING)),
],
)]
?name=foo evaluates is_granted("ROLE_ADMIN") (403 otherwise); the auth header
or ?secret=… must equal secured or the request is rejected. The parameter is
only checked when present — an absent or value-less parameter passes.
For query-level data isolation (multi-tenant, soft-delete) that must apply to every query regardless of operation, use a Doctrine extension or link handler instead — see securing-collections.
securityonly guards an already-fetched object; it does not scope collections.
Validation
API Platform runs Symfony's Validator on the deserialized object before the processor. Constraints live on the resource/input DTO (see custom-validator).
Validation groups per operation
#[ApiResource(
operations: [
new Post(validationContext: ['groups' => ['Default', 'user:create']]),
new Patch(validationContext: ['groups' => ['Default', 'user:update']]),
]
)]
#[Assert\NotBlank(groups: ['user:create'])] // required on create only
#[Assert\Email(groups: ['user:create', 'user:update'])] // checked on both
public ?string $email = null;
Collect denormalization errors
By default a type mismatch in the body throws on the first bad field. Enable
collect_denormalization_errors to report every malformed field at once in the 422
violations array:
#[Post(validationContext: ['collect_denormalization_errors' => true])]
Each malformed field becomes a violations entry with a propertyPath, a
This value should be of type … message, and a hint explaining the failure.
Validating query parameters
Attach constraints to a QueryParameter (or HeaderParameter); invalid values
yield 422 before the provider runs:
use ApiPlatform\Metadata\QueryParameter;
use Symfony\Component\Validator\Constraints as Assert;
#[GetCollection(
parameters: [
'page' => new QueryParameter(constraints: [new Assert\Positive()]),
],
)]
Deprecating endpoints
deprecationReason adds a Deprecation header; sunset adds a Sunset header
with the removal date. Apply at resource or operation level.
#[ApiResource(
deprecationReason: 'Use /v2/invoices instead.',
sunset: '2026-01-01T00:00:00+00:00',
)]
class Invoice {}
deprecationReason emits a Deprecation header and sunset a Sunset header. To
also advertise a migration doc, add an explicit operation links: entry —
new Link('deprecation', 'https://…') renders Link: <…>; rel="deprecation".
Nested PATCH gotcha
With application/merge-patch+json, to update an existing nested resource you
must include its identifier. Omitting it makes the serializer treat the nested
object as new (and attempt to create it):
{ "shippingAddress": { "id": 12, "city": "Lyon" } }
Without "id", API Platform tries to create a new Address rather than patch #12.
Laravel
Per-operation metadata (security, validationContext groups, collect_denormalization_errors,
deprecationReason/sunset, parameter validation/security) is mostly shared, but
auth and validation wiring differ:
- Authorization integrates with Laravel policies, not Symfony voters. Once a
policy exists, API Platform auto-maps operations to methods: GET collection →
viewAny, GET →view, POST →create, PATCH/PUT →update(PUT →createif absent), DELETE →delete. Override the mapping with apolicy:property on the operation:new Patch(policy: 'myCustomPolicy'). ThesecurityExpressionLanguage string also works. - Authentication / middleware is attached with the Laravel
middleware:property per operation (new Patch(middleware: 'auth:sanctum')) or globally underdefaults.middlewareinconfig/api-platform.php. - Validation uses Laravel
rules(array / closure /FormRequest) per resource or operation rather than SymfonyvalidationContextgroups — see the custom-validator Laravel section.AuthenticationException→ 401 andAuthorizationException→ 403 are mapped by default in the config'sexception_to_status. - Query/header
Parameterconstraintsare Laravel validation rule strings (e.g.'min:2'), not Symfony constraints.
Checklist
- Write operations restricted with
security/securityPostDenormalize - Collection isolation handled by an extension, not
security(see securing-collections) -
validationContextgroups split create vs update constraints -
collect_denormalization_errorsenabled where clients need full error lists - Query parameters carry validation constraints
- Deprecated endpoints set
deprecationReason+sunset
Bu becerideki dosyalar
1operations skill soruları
operations skill'ini Claude Code uygulamasına nasıl kurarım?
npx degit api-platform/skillset/skills/operations ~/.claude/skills/operations komutunu çalıştırın. Claude Code, skill'leri ~/.claude/skills (tüm projeler) veya .claude/skills (tek proje) konumundan yükler ve açıklaması görevle eşleştiğinde skill'i kullanır.
operations skill'ini hangi istemciler kullanabilir?
Agent Skills biçimini okuyan her istemci: Claude Code, Codex, Gemini CLI ve claude.ai (ZIP olarak yükleyin). Skill içindeki betikler yalnızca istemcinin kod çalıştırmaya izin verdiği yerlerde çalışır.
Bir uç noktasını sadece yöneticilerle sınırlandırabilir miyim?
is_granted('ROLE_ADMIN') gibi bir Symfony ExpressionLanguage dizesi ile security özniteliğini kullanabilirsiniz.
Bir kaynağı oluşturma ve güncelleme işlemleri için farklı doğrulama kuralları nasıl uygularım?
Farklı kısıtlama setlerini belirtmek için bir operasyonun validationContext'i içinde doğrulama gruplarını kullanabilirsiniz.
Sadece ilk hatayı değil, tüm hatalı alanları tek seferde nasıl raporlayabilirim?
422 yanıtında tüm ihlal listesini döndürmek için validationContext içindeki collect_denormalization_errors bayrağını etkinleştirin.