SurveyJS PHP Backend Integration with Laravel /

Use Relational Storage

Use Relational Storage

Use when: You need to query answers with SQL or join them with other application data.

Read this step in the docs

Try this

  1. Fill out the v1 form and press Complete. Data shows the responses row with definition_version: "v1", and the claims row with customer_email and amount filled.
  2. Switch the JSON schema to v2: the questions are renamed (contact_email, claimed_total) and moved into panels. Submit again: the same columns fill.
  3. Open the Load and Save Form JSON Schemas page and select a question: the Property Grid's Data category shows dbColumn. Back here, press Start over to submit another claim.

    No requests yet.

      What the server stored
      JSON schema v1: q_email, q_amount v2: renamed in Survey Creator

      Source on GitHub Definition: shared/definitions/relational-storage.v1.json, shared/definitions/relational-storage.v2.json

      Client · shared/client/relational-storage.js · sjs:relational-storage.client View on GitHub
      import { Model, Serializer } from "survey-core";
      
      // Optional: a custom property for richer mapping, editable in Creator's property grid
      Serializer.addProperty("question", { name: "dbColumn", category: "data" });
      
      // valueName fixes the key your columns read → response: { "customer_email": "...", "amount": 1840.5 }
      const survey = new Model(definitions[definitionVersion]);
      
      // Post the original response with the version of the definition it was filled against
      survey.onComplete.add(async (sender) => {
        await fetch("/api/claims", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ data: sender.data, definitionVersion })
        });
      });
      Server · routes/examples/relational-storage.php · sjs:relational-storage.server View on GitHub
      // POST /api/claims — original JSON first, then the columns you query
      Route::post('/api/claims', function (Request $request) {
          // The raw body, not $request->input(): PHP arrays would turn {} into [] in the stored JSON
          $body = json_decode($request->getContent(), flags: JSON_THROW_ON_ERROR);
          abort_unless(isset($body->data, $body->definitionVersion), 400, 'Expected { data, definitionVersion }');
      
          $id = DB::transaction(function () use ($body) {
              $responseId = StoredJson::insertResponse('claim', $body->data, [          // the original, stored as it arrived: 1.0 stays 1.0
                  'definition_version' => $body->definitionVersion,                    // keep the original and its version
              ]);
              DB::table('claims')->insert([                                            // keys come from valueName
                  'response_id' => $responseId,
                  'customer_email' => $body->data->customer_email ?? null,
                  'amount' => $body->data->amount ?? null,
              ]);
      
              return $responseId;
          });
      
          return response()->json(['id' => $id], 201);
      });