Erstellen eines internen API-Endpunkts, der es einem anderen Dienst ermöglicht, bestimmte Felder für Benutzer zu aktualisieren, die durch E-Mail-Adressen identifiziert werden. Wenn der Benutzer nicht existiert, muss er erstellt werden.Symfony Form CollectionType mit API-Beitrag neuer/bestehender Entitäten
Der Code funktioniert einwandfrei, wenn nur neue Benutzer gesendet werden.
Dies ist die POST-Anforderung an den API-Endpunkt.
[
{
"email":"[email protected]",
"favouriteFood": "pizza"
},
{
"email":"[email protected]",
"favouriteFood": "sweets"
}
]
Controller-Aktion
public function postUsersAction(Request $request)
{
$form = $this->createForm(UserCollectionType::class);
$form->submit(['users' => json_decode($request->getContent(), true)], true);
if (!$form->isValid()) {
return $form;
}
/** @var User $user */
foreach ($form->getData()['users'] as $user) {
$this->userManager->updateUser($user);
}
$this->em->flush();
return $form->getData()['users'];
}
UserCollectionType
class UserCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('users', 'collection', [
'allow_add' => true,
'by_reference' => false,
'type' => UserType::class
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
'cascade_validation' => true
]);
}
public function getBlockPrefix()
{
return '';
}
}
Usertype
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email')
->add('favouriteFood', TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => ['user_api'],
'cascade_validation' => true
]);
}
}
Wie kann ich den obigen Code aktualisieren, damit sie sehen wird überprüfen, ob der Benutzer vorhanden ist zuerst, sonst co noch ein neues erstellen, wie es derzeit funktioniert.
Ich hätte angenommen, dass ein DataTransformer verwendet worden sein könnte, aber nicht genau wie.
EDIT: Vorgeschlagene Lösung von ShylockTheCamel
Im Inneren des Controllers.
Ich habe die Frage mit wie ich Ihre vorgeschlagene Lösung anwenden würde aktualisiert. Fühlt sich nur ein bisschen hacky an und vermied es von vornherein. War neugierig, ob es eine bessere Lösung gibt, wie zum Beispiel, wo Symfony den Benutzer basierend auf 'data_class' erstellt. – Nick
Ich habe nicht vorgeschlagen, die Existenz eines Benutzers innerhalb des Controllers selbst zu überprüfen (was ziemlich dreckig ist)) aber innerhalb einer Validator-Klasse. Ich nehme an, Sie validieren das Formular, d. H. Die Felder E-Mail und favoriteFood gegen einige Einschränkungen, nicht wahr? Was ich vorgeschlagen habe, ist das Hinzufügen einer Einschränkung für E-Mails, um beispielsweise deren Nicht-Existenz zu überprüfen. Wenn der Test erfolgreich ist, führen Sie zusammen mit Ihrer anderen Einschränkung Ihre aktuellen Aktionen für einen neuen Benutzer aus. Wenn dies fehlschlägt, überprüfen Sie, ob die Nicht-Existenz-Einschränkung fehlgeschlagen ist und nicht die anderen, und wenn dies der Fall ist, handelt es sich um einen vorhandenen Benutzer. – ShylockTheCamel
Interessant, ich sehe nicht, wie das funktionieren würde. Wie bekomme ich eine bevölkerte Instanz in meine Controller-Schleife, da Validatoren keine Daten zurückgeben? – Nick