8

I'm trying to handle this problem: My app send JSON POST request with several information encoded in a Json. Example:

{"UserInfoA":{"1":123,"2":"hello","3":"bye","4":{"subinfo":1,"subinfo2":10}},
 "UserInfoB":{"a":"12345678","b":"asd"}} // and so on...

each UserInfo have:

  • Its own entity (although some request may have information of more than one entity).
  • A controller to persist this Object on DB and then give back the ID on this DB.

So, to achieve this problem I did another controller like JsonHandler, which receive this request and then forward to each controller after gut this JSON into differents objects. Example:

public function getJson (Request $request){
    if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
                $data = json_decode($request->getContent(), true);
            }
    if (!isset($data['UserInfoA'])){
         return new JsonResponse('ERROR');
              }
    $uia = $data['UserInfoA'];
    $idInfoA = $this->forward('Path::dataAPersist',array('data'=>$uia));
        }
    // same with userinfoB and other objects
    return $idInfoA ;

This works perfectly but Is it correct? Should i use services instead?

EDIT : I need to response the ID in a Json and this->forward returns a Response, so i can't use JsonResponse and if a send directly $idInfoA just send the IDNUMBER not in a JSON, how can i do it?

To sum up : a Json listener that receive the information, work it and then dispatch to the corresponding controller. This listener, should be a controller, a service or another thing?

3
  • Well, this is too broad. You should rephrase the question. Clearly describe what you want your code to do. Commented Oct 20, 2017 at 15:32
  • I want a module which handle JSON request and then send each Object (obtained after work with the JSON request) to the controllers that already exist to handle this object and persist in DB. So i made ANOTHER controller which have getJson method that do this and then call the respective methods in each controller. Commented Oct 22, 2017 at 20:36
  • E.g. have a look at Symfony Serializer, JMS and FOS RestBundle Commented Oct 27, 2017 at 8:11

5 Answers 5

12

I recommend the use of symfony-bundles/json-request-bundle since it does the JsonRequestTransformerListener for you. You just need to recieve the request parameters as usual:

...
$request->get('some_parameter');
...
Sign up to request clarification or add additional context in comments.

1 Comment

This is the way
7

hi you have to use service to make the Transformation

class php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class JsonRequestTransformerListener {


public function onKernelRequest(GetResponseEvent $event) {
    $request = $event->getRequest();
    $content = $request->getContent();
    if (empty($content)) {
        return;
    }
    if (!$this->isJsonRequest($request)) {
        return;
    }
    if (!$this->transformJsonBody($request)) {
        $response = Response::create('Unable to parse request.', 400);
        $event->setResponse($response);
    }
}


private function isJsonRequest(Request $request) {
    return 'json' === $request->getContentType();
}


private function transformJsonBody(Request $request) {
    $data = json_decode($request->getContent(), true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return false;
    }
    if ($data === null) {
        return true;
    }
    $request->request->replace($data);
    return true;
}
 }

And In Your Service.yml

    kernel.event_listener.json_request_transformer:
    class: You\NameBundle\Service\JsonRequestTransformerListener
    tags:
        - { name: "kernel.event_listener", event: "kernel.request",method: "onKernelRequest", priority: "100" }

Now You can call The Default request function to get Data

$request->request->all();

Comments

6

With Symfony 6 just use the getPayload() method.

Example:

$request->getPayload()->get('email')

It is as simple as it sounds.

1 Comment

Important caveat: this only allows scalar values
3

You can use symfony ParamConverter to to convert the json into any object you want and raise a meaningful Exception if anything goes wrong.

You can add custom ParamConverters and use them in your actions with annotation

Comments

3

Since Symfony 5.2, you can do a $data = $request->toArray();. With this, you would have an associative array with the JSON content parsed.

For example, with the next content:

{
  "id": 123,
  "name": "Someone"
}

You can have:

...
public function doSomething(Request $request) {
  $data = $request->toArray();
  $id = $data['id'];
  $name = $data['name'];
  doSomethingInteresting($name, $id);
}
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.