2

I have been working on a single page application project started a few weeks ago. We've focused so far on the front-end part of the project, built with AngularJS, which allowed for the validation of many aspects of the projected final application.

We're now setting up the web services and back end parts. Due to reasons I have no control over, Symfony has been chosen by the studio with which I am under contract. I am therefore encountering configuration and setup problems that I would not have met, had I been in my usual Java+Spring boot setting.

The existing application has this folder structure:

root-client
|--bower_components
|--images
|--libs (dist files of bower_components)
|--scripts
|--styles
|--views
|--index.html

I've initialized the Symfony project as per https://jeremycurny.com/2016/03/27/symfony3-rest-api/ and it works fine, returning the test JSON responses I've set up. Folder structure:

root-rest-api
|--app
|--bin
|--src
|--tests
|--var
|--vendor
|--web
|--...

Both parts work exactly as intended.

The problem comes when attempting to have both parts run together, that is when, following recommendations I've read in the Symfony documentation that static files are to be served from web, I moved everything below root-client under root-rest-api/web.

The problem is that index.html can no longer be reached from the web browser. More clearly, http://localhost/ used to start the application. After moving the "static" files under web, I now get this JSON response:

{"error":{"code":404,"message":"Not Found"}}

The cause of the error is easy to figure out: no controller is registered to the '/' path. As a consequence, I have written this:

namespace AppBundle\Controller;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends FOSRestController
{
    /**
     * @Rest\Get("/")
     */
    public function indexAction(Request $request)
    {
        return $this->render('index.html');
    }

This code defines a specific route for '/', which is what this answer to a similar question (in a Python environment instead of PHP or Symfony) points to.

I get a 500 HTTP error code, probably due to my improper use of render: all examples I've found online refer to Twig templates, for instance, the documentation about rendering templates. Even more undesirable to me, the examples place templates in app/Resources/views.

Is there a means of returning the existing index.html file from the web folder? I'm trying to avoid turning all our HTML fragments into Twig templates and thus redefining the Angular delimiters. Maybe that there's an obvious answer, but this is my first project using Symfony.

In case it's not possible, I'll treat the client and server parts as distinct projects and serve them as distinct layers of the architecture, instead of blending both as is the case with Java and Spring boot projects or classic Symfony projects.

Community
  • 1
  • 1
AbVog
  • 1,435
  • 22
  • 35
  • 1
    I'd highly recommend to define both `Angular Frontend` and `Symfony Backend` as two separate parts of your application then. As you're already planning to communicate between frontend and backend via REST this is a very common approach. Mixing it together will always lead into some little troubles. – LBA Mar 01 '17 at 09:02

1 Answers1

0

You always can use good old file_get_contents($index_html_path), and send simple string response, in your case (Symfony 4):

    /**
     * @Route("/", name="index_page")
     */
    public function indexAction(Request $request)
    {
        return new Response(file_get_contents($index_html_path));
    }

How to get path to index html? It is simple in controller:

    $index_html_path = $this->getParameter('kernel.project_dir') . '/public/index.html';

Or even so, if your index.html is simple and rarely changing (just copy-past content to your controller):

    /**
     * @Route("/", name="index_page")
     */
    public function index() {
        ?>
        <!doctype html>
        <html lang="en">
        <head>
            <title></title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        </head>
        <body>
        <div id="root"></div>
        </body>
        </html>
        <?php
        return new Response("");
    }
basil
  • 3,482
  • 2
  • 22
  • 20