2

I have an AngularJS application backed by a RESTful Symfony app. I have a problem to POST users (e.g. POST /api/users/123).

Here is what Symfony Form expects in a POST request (to edit or submit a resource):

{
  "user": {
    "email":"foo@mnapoli.fr"
  }
}

You see here that the object that is being posted is wrapped in another user: {…} object (that represents the form).

Here is what Angular's $resource will post when calling user.$save():

{
  "email":"foo@mnapoli.fr"
}

Here there is no wrapper. The object is posted directly.

  • which one is "correct", i.e. RESTful?
  • how can I make Symfony, or Angular, work with the other (based on the previous answer)?
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261

3 Answers3

3

Here is how I managed to solve it, but I'm eager for a cleaner solution if it exists.

It turns out the name of the form type can be empty:

class UserType extends AbstractType
{
    // ..

    public function getName()
    {
        return '';
    }
}

That makes this a valid submission:

{
  "email":"foo@mnapoli.fr"
}
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
  • I think this is a perfectly valid solution. Even @BernhardSchussek recommended it (although [for some other problem](http://stackoverflow.com/a/13474522/838733)). – nietonfir Jul 10 '14 at 21:54
  • Thanks for the link @nietonfir It also confirms what I've read in the code (it seems to be a valid use case). I'll accept that answer for now (when SO allows me), and switch if a better alternative pops up. – Matthieu Napoli Jul 10 '14 at 22:04
  • I digged in to code and came to same solution but think there should be better way to do it. Did you get any better solution ? – vishal Nov 24 '14 at 10:19
  • @vishal nope, apparently that's how it's meant to be… – Matthieu Napoli Nov 24 '14 at 22:21
0

A valid POST request to create a resource in a restful way doesn't have an id. By definition you can PUT to an id. If the target exists it is edited, if not it gets created. Concerning your first question, the second form would be more "correct".

Basically you define the form type, so it's completely up to you (there is no "it expects"). An example could be

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email')
        ;
    }

    public function getName()
    {
        return 'user_form';
    }
}

And then in your controller you pass it an empty user entity

public function newAction()
{
    $user = ...;
    $form = $this->createForm(new UserType(), $user);

    // ...
}

See the official book chapter about SF2 forms for more.

nietonfir
  • 4,797
  • 6
  • 31
  • 43
  • Hi, I think we are not talking about the same thing. The difference between the 2 formats is not about ids, it's that Symfony expects the object to be wrapped inside another object representing the form (i.e. `user: {…}`) whereas Angular will directly post the object itself, without wrapping it. I've updated my question a bit. – Matthieu Napoli Jul 10 '14 at 20:52
  • Now I know what you mean, you have a problem with the name of the form type that gets normally prepended to the input field names. – nietonfir Jul 10 '14 at 21:32
  • Yes that's just that! – Matthieu Napoli Jul 10 '14 at 21:39
0

As far as I know you can submit just the specific form data rather than the whole array with the form name as a key like..

$form->submit($request->get($form->getName()));
// or $request->request (for POST)
// or $request->get (for GET)
// to be more specific

With this being known you should then just be able to use..

$form->submit($request->all());
// again with ->request or ->get to be more specific

.. to submit all of the request data as the actual form data without the need for the form name as the key.

This does mean that any extra fields, if any, would be submitted to the form too and possibly cause some of those "This form should not contain extra fields."

qooplmao
  • 17,622
  • 2
  • 44
  • 69