Symfony2 invalid form still saves entity on flush - symfony

I currently have a form and on save I always make an API call to validate the form information against an external source (eg: is the company a VAT paying company etc.). I also want to store in the database the response I get from the external API, for which I have a post submit subscriber on the form.
In the subscriber, I call the API and set errors on the form where values do not match. That is where I call a service to handle all the business logic and somewhere in there I have
$em->persist($apiResponse);
$em->flush();
to hold onto the API response.
This ends up saving the entity values attached to the form (company) in the database even though these values are actually invalid and the user is returned to the form page saying that.
Please note this happens on edit, and I understand why it happens, because the entity is managed by Doctrine.
I also tried flushing only the entity I am interested in:
$em->persist($apiResponse);
$em->flush($apiResponse);
and this seems to work, but I read this can have an unexpected behavior.
Hence, my question is: what are the solutions for this ?
Thank you, and sorry for the lack of code samples!

Related

Contract Tests for APIs which involve session or workflow

Hi I am trying to write Contract Tests for a product purchase workflow. So obviously i cannot call the Checkout API directly without calling Add to Cart API.
But as I have observed the verification hits the paths individually might not be in the same order as listed in the Pact JSON File.
So how should I handle such scnenario which involve session management and workflow(meaning step1 shud be successful only then step2 will be success)
Thanks!
Use provider states to set up the right data in the cart so that when you call checkout, you get the behaviour you want. Here's the documentation from pact.io on provider states.
Each interaction in a pact should be verified in isolation, with no context maintained from the previous interactions. Tests that depend on the outcome of previous tests are brittle and land you back in integration test hell, which is the nasty place you're trying to escape by using pacts.
So how do you test a request that requires data to already exist on the provider? Provider states allow you to set up data on the provider by injecting it straight into the data source before the interaction is run, so that it can make a response that matches what the consumer expects. The name of the provider state is specified in the given clause of an interaction in the consumer, and then used to find the block of code to run in the provider to set up the right data. If you need to stub a downstream system, or return an error response that is difficult to cause in the normal scheme of things (e.g. a 500), this is the place where you can set up stubs.
https://docs.pact.io/documentation/provider_states.html
In your case, this would look like:
Given an item has been added to the cart
upon receiving a request to checkout it will respond with the checkout response....
As an aside, I would also imagine you'd want, given no items have been added to the cart upon receiving a request to checkout it will respond with some other type of response (empty cart? error?)
The provider will need to implement the provider state hook for an item has been added to the cart in the verification code, which will add the item to the cart by inserting it directly into the datasource.

Save query result from GET method for future reference

I want to implement a query on my web page that gets results from another web service and displays them to the user. For this I ofcourse send the request as GET method from the web page. Server side, I process the request, get results from that web service and return them back to user.
However, I also want to save the results for future refernce. Something like history of queries. For this I will store the results in a database.
Now, the question is since I am upating my database everytime a query is made, should I be using POST method on the web page or GET would do? Does HTTP explicitly say anything for this scenario?
HTTP itself doesn't say you have to use POST -- the technology will work just fine if you're sending your data on queryparams.
But current convention says that you should use POST, specifically when using API services under a RESTful model. If you are passing data (even on the query params) that is creating a new record, it should use the POST verb. Updating it should use PUT.
It's going to get down to what your audience expects. If it's just an internal resource, go for it with GET. If you expect to open this up as a public service, use POST.

What actions are considered to be idempotent in RESTfull scenarios?

Consider I want to develop a RESTfull WebApi for a Book Store. I'll have an Api to get a book info like: books/1.
I want to create a log whenever someone gets a book info. So, later I can produce a report of which book is seen more through the Api.
As in this scenario I'm getting some information it seems more appropriate to use GET. But as it changes some data, it could be a SET request.
Question: Does some changes like Logging effect on idempotent behavior of an action?
The general pattern is that a GET of a resource should not modify the resource in such a way that a subsequent GET of the same resource gets a different result.
Side-effects such as logging are not part of the data model, so are not generally considered to be related to whether the action is idempotent or not.

symfony2 and Doctrine2 - upload as a service

I'm learning Symfony2 and need some advice. I have two entities, the first entity "Issue" has a OneToMany relationship with the second entity "Attachment". When posting an Issue form I am successfully uploading all child attachments, everything works hunky-dory :) but now I want to turn my upload solution into a service and that's where I'm getting confused. The uploads are processed in my Attachment model and my controller simply reads as follows :
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
....
From what I understand a service can be accessed from a controller using the "get" method but because I do not process my attachments in the controller and never instantiate the "Attachment" model from the controller how do I pass it an upload service? Instantiating it within the Attachment entity construct appears to defeat the object of the exercise doesn't it?
Forgive me if I am talking rubbish. Idiot friendly guidance would be appreciated.
EDIT:: Further to the feedback, should uploads be treated as a service processed in the controller or could they be a behaviour associated to a model? Which way to jump.
I'm doing something similar in ZF2 - but I use my controller still to process and receive the upload, then use the Service to extract the uploads, register them into the database etc.
I get the name of the file where it's temporarily uploaded to and pass that through to the service (i.e /tmp/up2029398393). That then moves it to where it's supposed to be, creates the entity and does the persist & flush for that object

Symfony2: Is better to use session object or my own manager?

Related to that question.
I've understood that I have to create some services for handle my entity and so on. That's because I have to "move" my logic away from controllers and place into "managers" (i.e. services)
Now I have a service that have some logic into it. In that service I, depending on user, return a list of "associated object" - say that those object are sport's team.
Let's say that first element of my list (generated from a repository somehow) is the "default" team and say that I have a page were I can change it FOR all session long.
After log out or sessions stale, I want to return at "default" situation.
So my idea was: "since I've wrote a manager for this entity, I'll write a private attribute in this class where load (from db) this property and store (temporarily, with setter method) my changes."
This doesn't affect my db and I can keep my information for all session long.
But a thought came into my mind: how about session object? (is a service, if I didn't understood wrong)
Is my solution a good solution, or is better to store my information into session object?
From my point of view it's the same except that I can read session's variables directly from twig by using app.session. Am I wrong?
Moreover, if I'm not wrong, how can I access my object properties from twig without each time pass them from controller? (is much like having a global variable that I want to display everywhere into my application pages).
Edit:
More information can be found in this chat transcript.
If you want to store a variable for the duration of a session (for example, login until logout or as long as the user doesn't close his browser window) you have to store it in the session object. If you want to store a variable for the duration of a request, you can store it in the manager service.
However, you can use the manager service to load the session variable and make it available to the controller.
Just like it is a good idea to decouple the controller from the database/Doctrine it is also a good idea to decouple the controller from the session.
Update: As mentioned in the comments when looking at REST it is not a good idea to do the session stuff in the service. However, you should still store the variables in the session and use the controller to set the value in the service.

Resources