@matarld
@matarld
mtarld
les-tilleuls.coop
@matarld
@matarld
REST -Principles
@matarld
End of the presentation, press any key to exit...
@matarld
(that we can access from another resource)
@matarld
@matarld
Last minute feature
@matarld
GET /players?team=france
@matarld
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
#[ApiResource]
+ #[ApiFilter(SearchFilter::class, properties: ['team.id' => 'exact'])]
class Player
{
// ...
}
@matarld
GET /players?team=thatsatypo
{
"@type": "hydra:Collection",
"hydra:member": []
}
@matarld
GET /players?team=france
the player resources
that belongs to france team
@matarld
resource
subresource
GET /teams/france/players
@matarld
- API Platform and subresources -
@matarld
PATCH /teams/france/players/dupont
GET /teams/france/players/dupont
GET /teams/france/players
DELETE /teams/france/players/dupont
PUT /teams/france/players/dupont
POST /teams/france/players
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
#[ApiResource]
class Team
{
#[ApiSubresource]
private Collection $players;
// ...
}
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
#[ApiResource]
class Team
{
#[ApiSubresource]
private Collection $players;
// ...
}
@matarld
use ApiPlatform\Metadata\{ApiResource,Get,GetCollection,Link};
#[ApiResource]
#[GetCollection(
uriTemplate: '/teams/{teamId}/players',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
],
)]
#[Get(
uriTemplate: '/teams/{teamId}/players/{playerId}',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
'playerId' => new Link(fromClass: Player::class),
],
)]
class Player
{
public Team $team;
}
GET /players
GET /players/{p}
POST /players
PUT /players/{p}
PATCH /players/{p}
DELETE /players/{p}
GET /teams/{t}/players
GET /teams/{t}/players/{p}
@matarld
uriTemplate: '/teams/{teamId}/players',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
],
@matarld
{
"@type": "hydra:Collection",
"hydra:member": [
{"@id": "/players/dupont"},
{"@id": "/players/fickou"}
]
}
@matarld
#[ApiResource]
#[GetCollection('/teams/{teamId}/players')]
#[Get('/teams/{teamId}/players/{playerId}')]
class Player
{
public Team $team;
}
#[Get]
#[GetCollection]
#[Put]
#[Patch]
#[Post]
#[Delete]
#[GetCollection('/teams/{teamId}/players')]
#[Get('/teams/{teamId}/players/{playerId}')]
class Player
{
public Team $team;
}
@matarld
#[GetCollection(
uriTemplate: '/teams/{teamId}/players',
+ itemUriTemplate: '/teams/{teamId}/players/{playerId}',
)]
#[Get]
#[GetCollection]
#[Put]
#[Patch]
#[Post]
#[Delete]
#[GetCollection('/teams/{teamId}/players')]
#[Get('/teams/{teamId}/players/{playerId}')]
class Player
{
public Team $team;
}
@matarld
{
"@type": "hydra:Collection",
"hydra:member": [
{"@id": "/teams/france/players/dupont"},
{"@id": "/teams/france/players/fickou"}
]
}
@matarld
resources:
App\Entity\Player:
operations:
ApiPlatform\Metadata\GetCollection:
uriTemplate: /teams/{teamId}/players
uriVariable:
teamId: { fromClass: App\Entity\Team, toProperty: team }
itemUriTemplate: /teams/{teamId}/players/{playerId}
ApiPlatform\Metadata\Get:
uriTemplate: /teams/{teamId}/players/{playerId}
uriVariable:
teamId: { fromClass: App\Entity\Team, toProperty: team }
playerId: { fromClass: App\Entity\Player }
@matarld
Urging feature
@matarld
GET /players/{playerId}/sprints
GET /players/{playerId}/sprints/{sprintId}
@matarld
#[GetCollection(
uriTemplate: '/players/{playerId}/sprints',
uriVariables: [
'playerId' => new Link(fromClass: Player::class, toProperty: 'player'),
],
itemUriTemplate: '/players/{playerId}/sprints/{sprintId}',
)]
class Sprint
{
public Player $player;
}
@matarld
#[GetCollection(
uriTemplate: '/players/{playerId}/sprints',
uriVariables: [
'playerId' => new Link(fromClass: Player::class, toProperty: 'player'),
],
itemUriTemplate: '/players/{playerId}/sprints/{sprintId}',
)]
#[Get(
uriTemplate: '/players/{playerId}/sprints/{sprintId}',
uriVariables: [
'playerId' => new Link(fromClass: Player::class, toProperty: 'player'),
'sprintId' => new Link(fromClass: Sprint::class),
],
)]
class Sprint
{
public Player $player;
}
@matarld
#[Get(
+ status: 404,
uriTemplate: '/players/{playerId}/sprints/{sprintId}',
- uriVariables: [
- 'playerId' => new Link(fromClass: Player::class, toProperty: 'player'),
- 'sprintId' => new Link(fromClass: Sprint::class),
- ],
)]
@matarld
#[Get(
status: 404,
+ openApi: false,
uriTemplate: '/players/{playerId}/sprints/{sprintId}',
)]
@matarld
#[NotExposed(
uriTemplate: '/players/{playerId}/sprints/{sprintId}',
)]
@matarld
Very important feature
@matarld
GET /stadium/gerland/matches/fr-nz/orders/001/lines/a6b993249c88/seats
Stadiums
Matches
Orders
Order lines
Seats
@matarld
GET /matches/fr-nz/orders
1
30000
90000
GET /orders/{order}/lines
1+N
GET /lines/{line}/seats
1+N+Σɴ(M)
@matarld
GET /seats?stadium=gerland&match=fr-nz&status=sold
1
@matarld
Last feature
@matarld
POST /teams/italy/injuries
@matarld
#[Post(
uriTemplate: '/teams/{teamId}/injuries',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
],
)]
class Injury
{
public Team $team;
}
@matarld
{
"player": "/players/ceccarelli",
"type": "sprain",
"duration": 10,
"team": "/teams/italy"
}
POST /teams/italy/injuries
"/teams/italy"
/teams/italy
@matarld
{
"player": "/players/ceccarelli",
"type": "sprain",
"duration": 10
}
POST /teams/italy/injuries
/teams/italy
@matarld
#[Post(
uriTemplate: '/teams/{teamId}/injuries',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
],
)]
@matarld
#[Post(
uriTemplate: '/teams/{teamId}/injuries',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, toProperty: 'team'),
],
+ extraProperties: [
+ 'parent_uri_template' => '/teams/{teamId}',
+ ],
)]
@matarld
The very last feature
@matarld
#[Get]
class Match
{
public string $score;
/** @var list<Event> */
public array $events;
}
@matarld
{
"@id": "/matches/fr-nz",
"score": "27-13",
"events": [
{
"@id": "/events/97b470a",
"actor": "https://schema.org/Referee",
"value": "https://ffr.fr/enums/events/kick_off"
},
{
"@id": "/events/46a0368",
"actor": "https://schema.org/Player",
"value": "https://ffr.fr/enums/events/hit_ball"
},
{...}
]
}
@matarld
#[Get]
class Match
{
public string $score;
/** @var list<Event> */
+ #[ApiProperty(readableLink: false)]
public array $events;
}
@matarld
{
"@id": "/matches/fr-nz",
"score": "27-13",
"events": [
"/events/97b470a",
"/events/46a0368",
"..."
]
}
@matarld
#[Get]
class Match
{
public string $score;
/** @var list<Event> */
- #[ApiProperty(readableLink: false)]
+ #[ApiProperty(uriTemplate: '/matches/{id}/events')]
public array $events;
}
@matarld
{
"@id": "/matches/fr-nz",
"score": "27-13",
"events": "/matches/fr-nz/events"
}
{
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/matches/fr-nz/events/97b470a",
"actor": "https://schema.org/Referee",
"value": "https://ffr.fr/enums/events/kick_off"
},
{
"@id": "/matches/fr-nz/events/46a0368",
"actor": "https://schema.org/Player",
"value": "https://ffr.fr/enums/events/hit_ball"
},
{...}
]
}
?preload=/events
@matarld
The ultimate last feature (pinky promise!)
@matarld
GET /teams/france/sponsors/le-coq-sportif
@matarld
GET /teams/france/sponsors/le-coq-sportif
GET /sponsors/le-coq-sportif
@matarld
#[Get]
#[Get(
uriTemplate: '/teams/{teamId}/sponsors/{sponsorId}',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, fromProperty: 'sponsor'),
'sponsorId' => new Link(fromClass: Sponsor::class),
],
)]
class Sponsor
{
}
@matarld
#[Get]
#[Get(
+ status: 301
uriTemplate: '/teams/{teamId}/sponsors/{sponsorId}',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, fromProperty: 'sponsor'),
'sponsorId' => new Link(fromClass: Sponsor::class),
],
)]
class Sponsor
{
}
@matarld
@matarld
#[Get]
#[Get(
status: 301
uriTemplate: '/teams/{teamId}/sponsors/{sponsorId}',
uriVariables: [
'teamId' => new Link(fromClass: Team::class, fromProperty: 'sponsor'),
'sponsorId' => new Link(fromClass: Sponsor::class),
],
+ extraProperties: [
+ 'canonical_uri_template' => '/sponsors/{sponsorId}',
+ ],
)]
class Sponsor
{
}
@matarld