Creating common classes for client and server apps

In distributed apps such as the client-server pattern, you often want to work with the same model classes on both ends. Why? Because client input needs to be validated at the client side and for this, we need the model in the client app. Data has to pass through the model before being stored so that if we want to store the data in a client database (indexed_db) as well as in a server data store, we need the model on both the sides.

How to do it...

You can see how common classes are created for client and server apps in the client_server_db app. This is a to-do application; the client is started from web/app.html and the server is started from bin/server.dart. The client stores the to-do data in indexed_db, while the server stores the data in memory. Both client and server need the model classes.

The project structure is shown in the following screenshot:

How to do it...

Common library

How it works...

If you want to be able to import your common model library from another package, the files must be under the lib directory. In this example, we see from pubspec.yaml that the name of the app is client_server. The model (with the Task and Tasks classes) has its own folder lib/model, which contains the model classes defined in the shared_model library within lib/shared_model.dart. The client-app web/app.dart uses indexed_db; it therefore imports a library idb_client to work with indexed_db, as shown in the following code:

import 'package:client_server/idb_client.dart';

The idb_client library, defined in lib/idb_client.dart, imports the shared_ model library, as shown in the following code:

library idb_client;

import 'package:client_server/shared_model.dart';
import 'dart:async';
import 'dart:html';
import 'dart:indexed_db';
import 'dart:convert';

part 'idb/idb.dart';
part 'view/view.dart';

In this way, the client app knows about the model. The server app also knows about the model by importing it (see bin/server.dart):

import 'dart:io';
import 'dart:convert';
import 'package:client_server/shared_model.dart';
// rest of code

There's more…

Here's another common use case for shared models; say the class has a method that performs HTTP requests; on the client, you will use HttpRequest from the dart:html library, while on the server, you will use the one from dart:io instead. For security reasons, both dart:io and dart:html cannot be imported in the same library, so it's a common practice to define the shared class as an abstract class, and then delegate the concrete implementation of the HttpRequest method to both the client and server classes, which extend the shared abstract class.

See also

  • Refer to the Structuring an application and Making and using a library recipes in Chapter 2, Structuring, Testing, and Deploying an Application for your app
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset