Symfony Restful Post: JMSSerializerBundle vs Symfony Form Components - forms

As far as i understand it right JMSSerializerBundle's deserialisation does the same same as the symfony form component when a controller gets an post/put/patch request?
So either i create a symfony custom formType for e.g. an UserType and when i get a request i do something like $form->handleRequest($request) or i use JMSSerializerBundle to unserialize the request to a document/entity which gets finally stored.
Does anyone have experience with both methods? Currently i'm only familiar with the form way... Which one should i choose?
The Application i'm talking about is purely Restful, there are no twig html templates and FOSRestbundle is doing all the RESTful routing.

In our restfull API we usually use the Symfony Serializer component to handle the deserialization of entities, then the Symfony Validator component to ensure that the entities fulfill all the required conditions before pushing/updating them in database. Works pretty well, lighter than the form component.
Anyway The Form component would not be able to deserialize the json/xml so you'll have to use a serializer.

The benefit of the Symfony\Form component over the JMS Serializer is that the validation is done before deserialization which fits into PHP 7 strict typing. Example case - you pass an array instead of a string, JMS creates and object and the getter raises a \TypeError instead of a validation error from the validator.

Related

Symfony 3 REST API POST validation

What is the "best" way to handle entities validation in a Symfony3 REST application?
I know that I could use Form to do it and use its already existing validators (required, email type, repeat type, ...).
Might I also use the entity repository or another service to validate, serialize, unserialize my entities, thus having all the entity IN/OUT logic at the same place? But then how should I handle validation during both creation and update when data might not all be present?
Any thought?
Process the request through a Controller
Use a Form to process that request
Build custom validators or leverage existing on the FormClass
Using your controller (#1) handle PUT and POST and PATCH separately with unique actions.
Serialize/deserialize your request/response in the controller OR using a handler that the controller (#1, #4) hands the request off to.
Thanks for your inputs. I'll use the Doctrine Assert validators to handle the validation and the Symfony\Component\Validator\Validation class.
Regarding the Symfony3 documentation I think this is probably the best option.
https://symfony.com/doc/current/validation.html
another way, in my project, i not apply form for entity, maybe you need this way
Helper:
Base function :
Create action in controller
Update Action in controller

JAX-RS Struts2 REST API

Why would one like to integrate JAX-RS(Jersey) using Rest API to Struts2? Struts2 is itself a mvc framework, so why would anyone want to integrate these both? If combined, how will the resulting framework be(I wanted to know if REST API just control the controller part of MVC).
There is a RESTful plugin called struts2-rest-plugin that has been included with the framework since version 2.1.1. A fair amount of information on the plugin can be found here.
Essentially, the plugin uses a custom action mapper that examines the request and based upon the HTTP Method used in conjunction with the URI, it dispatches the request to one of several different method names (e.g. GET /movies dispatched to index() method of action).
Just because Struts2 is an action-based framework does not mean a RESTful solution cannot be included as an alternative for developers. Spring MVC offers similar solutions themselves and it is also an action-based framework.
If you consider your JSON response as your view, you'll see that the fact that Struts2 is based on MVC design makes logical sense. Your model is simply the data structure you are returning to the client and your controller is the action.
Consider reading the link above on the plugin and you'll get a better picture of how the two can be integrated. If you want to return JSON but don't necessarily want to offer RESTful URLs in your Struts2 application, you can also consider the JSON plugin, found here.
I am not sure about Struts2, but in the past Struts1 did not have a "Rest" adapter built in. Jersey provides the cool #annotations that will easily serialize your datamodel and will push you in a "Restful" direction. Jersey does not provide an MVC framework as much as it provides convenience methods to work in a Restful/resource based way.

Strategies for making FOS RestBundle and json HAL integratable in RESTful apis

What would be good strategies/approaches to integrate the HAL specification with the FOSRestBundle?
A rather simple approach would be to create a plain PHP entity to represent HAL in its entirety, and then send the object back with each response. Although this can work quite well, I think it should be integrated with listeners. That would require some thinking, and potentially the topics below would have to be covered:
Error handling (eg. Exception and Form Validation)
Resource representation (eg. the main resource directly in the body, whilst associated resources in the _embedded property)
HATEOAS (_links pointing to other URIs eg. pagination)
You will probably love the Hateoas library, and its Symfony2 bundle: BazingaHateoasBundle.
If you whant to implement Hal specification, there is a bundle for that alterway/RestHalBundle. You do not need to implement it in FOSRestBundle.
And for error handling : alterway / RestProblemBundle
Take a look at http://www.apigility.org by ZF2 team. Apigility serves in JSON HAL format.
Here is a nice article on how to integrate a Symfony2 app with Apigility: http://www.zimuel.it/create-api-symfony2-apigility

Symfony2 And Single Webpage Applications using a framework like AngularJS

(If this is not the right place to post this kind of question I'd happily post it somewhere else)
I'm trying to build an interactive web application to manage company resources.
I have experience with Symfony2 but I kind of hit a wall with this new application.
I'd like to make this application quite interactive on the client side. Almost a full single webpage application.
My previous web applications would normally just use a typical MVC pattern with CRUD pages.
In those simple applications I would have
/employees/
/employees/create
/employees/detail/45
/employees/update/45
/employees/delete/45
Using symfony in this kind of application would give me a lot of advantages:
Routing
Security (CSRF tokens)
FormTypes and Form handling
Validation
Integration with Doctrine
Twig
Especially functionality like this in Twig was very refreshing (since my models were build as Doctrine entities):
<p>{{ employee.getCurrentTask().description }}</p>
The problem I'm facing now is that I feel like Symfony2 isn't really build for single webpage applications. As soon as I try to add some Ajax functionality I'm faced with these problems:
CSRF tokens invalid
Too much non reusable view/presentation logic in jQuery
Adding data-attributes in html to get id's etc...
I then looked into Knockout.js and Angularjs but then I feel like lose all of the advantages of Doctrine and Twig. I have to rebuild my models on the client side anyway and have to maintain them in two different locations then.
So I came up with this idea:
Use Symfony2 models and controllers to persist data to the database but let controllers in symfony just send out JSON and receive JSON (FOSRestBundle maybe?)
Use a framework like AngularJS or KnockoutJS to rebuild that JSON data on the client side to use 2-way binding.
But then how would I tackle the issues like Doctrine2 Relationships, Form Validation, CSRF which Symfony already solved but are unusable if I use a frontend js framework?
All suggestions are welcome!
Some words about JSON, Serialization and Models
Simon, I faced exactly the same questions and problems. First like ken already mentioned. You don't need to rebuild any model. Better use FosRestBundle and/or JMS Serializer. It turns you entities with relations into JSON objects. This objects are transferred via api to your frontend and you can work with them just like in twig, when you use angular.js like this
{[{ user.username }]}
is as same as in twig. But remember that you have to set custom brackets for angular because by default it uses the same as twig.
Routing
You talk of a single page application, so symfony's routing is kept on a low level to have few page refresh. Instead you have to use routing of your frontend framework, because I am only familiar with angular.js, I give an angular example:
app.config(function($routeProvider, $interpolateProvider) {
//here you go, custom brackets
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
$routeProvider.when('/user', {
controller: UserController,
templateUrl: Routing.generate('suser_list')
}).when('/ticket', {
controller: TicketController,
templateUrl: Routing.generate('ticket_list')
});
});
When you hit a link like
Go to tickets
AngularJs will know which frontend controller to trigger. Pretty great stuff, without page reload. Also have a look at FosJSRoutingBundle. It allows you to generate symfony routes in javascript, I use them to link js controllers with html templates where data is pushed in.
FormTypes, Form handling, Validation
Well, when you use a frontend framework like angularjs, your symfony form types are pretty useless. But I am not sure. Remember data is pushed and pulled via api as json, I think this would be a hard job for form types to handle this kind of compexity.
For validation you can use angular's live validation or have you symfony's validation in the backend, no problem. It might be a good thing to use both, client and server side validation.
Twig
Twig is out of the race. All data is rendered on the client side, and not pre rendered on server side like with twig. But that is only the case if your application is really a single page application. Of course you can use twig, but it will only refresh if you reload the entire page.
Integration with Doctrine
You can still use doctrine in the backend. Do you have a specific question regarding doctrine and SPA?
You don't need to rebuild the model in client. I normally just create a service in angularjs that provides json data. Data manipulation still happens server side using ajax.
For forms that requires csrf, I normally just send the html rendered by twig via json. Or you can serialize $form->createView() with jms serializer. However you will need some client script to transform the json data to actual form controls.

Forcing all controls on MVC2 form to validate using JQuery

Is there a way (using JQuery or Java Script) to force an MVC2 form to perform validation on it's fields with Data Annotation validation without posting back to the server?
I have a MVC2 form that is quite complex. Many of the fields are hidden or displayed depending on other selections. Given this, some of the fields are validated using Data Annotations and some are validated using custom JQuery.
In the case that one of the fields with custom validation fails it's validation I wish to prevent the form from posting back however this stops any of the fields with Data Annotation Validation from working.
Thanks.
IMHO mixing jquery validate with MSAjax is a bad thing. For complex forms with many custom validation rules I would recommend using only jquery validate and on the server a more powerful validation framework than DataAnnotations such as FluentValidation.NET which works nicely with ASP.NET MVC.