Repository: oppia/oppia

Issue:
The exploration data handler should be migrated to ReadOnlyExplorationBackendApiService and EditableExplorationBackendApiService
All references to the ``'/createhandler/data/<exploration_id>'`` handler in the frontend should be updated to instead use a ``ReadOnlyExplorationBackendApiService`` and ``EditableExplorationBackendApiService``. For references of what these objects and their corresponding tests should look like, the corresponding services for collections can be closely used:

- [ReadOnlyCollectionBackendApiService](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/ReadOnlyCollectionBackendApiService.js), [ReadOnlyCollectionBackendApiServiceSpec](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/ReadOnlyCollectionBackendApiServiceSpec.js)
- [EditableCollectionBackendApiService](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/EditableCollectionBackendApiService.js), [EditableCollectionBackendApiServiceSpec](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/EditableCollectionBackendApiServiceSpec.js)

Unlike the collection backend services, the exploration backend API services do not need to return an exploration domain object yet. This is because migrating the exploration editor to using a domain object is a larger effort. These services should go under ``domain/exploration``.
The exploration data handler should be migrated to ReadOnlyExplorationBackendApiService and EditableExplorationBackendApiService
All references to the ``'/createhandler/data/<exploration_id>'`` handler in the frontend should be updated to instead use a ``ReadOnlyExplorationBackendApiService`` and ``EditableExplorationBackendApiService``. For references of what these objects and their corresponding tests should look like, the corresponding services for collections can be closely used:

- [ReadOnlyCollectionBackendApiService](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/ReadOnlyCollectionBackendApiService.js), [ReadOnlyCollectionBackendApiServiceSpec](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/ReadOnlyCollectionBackendApiServiceSpec.js)
- [EditableCollectionBackendApiService](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/EditableCollectionBackendApiService.js), [EditableCollectionBackendApiServiceSpec](https://github.com/oppia/oppia/blob/develop/core/templates/dev/head/domain/collection/EditableCollectionBackendApiServiceSpec.js)

Unlike the collection backend services, the exploration backend API services do not need to return an exploration domain object yet. This is because migrating the exploration editor to using a domain object is a larger effort. These services should go under ``domain/exploration``.


Discussion:

Resolving patch:
diff --git a/core/controllers/reader.py b/core/controllers/reader.py
--- a/core/controllers/reader.py
+++ b/core/controllers/reader.py
@@ -233,9 +233,10 @@ def get(self, exploration_id):
                 rights_manager.Actor(self.user_id).can_edit(
                     feconf.ACTIVITY_TYPE_EXPLORATION, exploration_id)),
             'exploration': exploration.to_player_dict(),
+            'exploration_id': exploration_id,
             'is_logged_in': bool(self.user_id),
             'session_id': utils.generate_new_session_id(),
-            'version': exploration.version,
+            'version': exploration.version
         })
         self.render_json(self.values)
 
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -299,7 +299,8 @@ def ui_access_wrapper(self, *args, **kwargs):
         r'%s/<exploration_id>' % feconf.EDITOR_URL_PREFIX,
         editor.ExplorationPage),
     get_redirect_route(
-        r'/createhandler/data/<exploration_id>', editor.ExplorationHandler),
+        r'%s/<exploration_id>' % feconf.EXPLORATION_DATA_PREFIX,
+        editor.ExplorationHandler),
     get_redirect_route(
         r'/createhandler/download/<exploration_id>',
         editor.ExplorationDownloadHandler),


Test patch:
diff --git a/core/controllers/editor_test.py b/core/controllers/editor_test.py
--- a/core/controllers/editor_test.py
+++ b/core/controllers/editor_test.py
@@ -296,6 +296,7 @@ def _submit_answer(
             self.assertEqual(
                 response_dict['unhandled_answers'],
                 _create_training_data('joyful', 'sad'))
+            self.assertTrue(exploration_dict['version'])
 
             # If the confirmed unclassified answers is trained for one of the
             # values, it should no longer show up in unhandled answers.