dart bin/main.scriptin a Conduit project directory. Either way, a number of threads are created and your
ApplicationChannelsubclass is instantiated on each thread. The channel subclass initializes application behavior which is often the following:
UserController. Because the router is returned from this method, it handles all incoming requests. It will pass a request to an
Authorizerwhen the request path is
/users, which will then pass that request to a
UserControllerif it is authorized.
link()method takes a closure that creates a new controller. Some controllers get instantiated for each request, and others get reused for every request. See the chapter on controllers for more information.
entryPoint. You store created services in instance variables so that you can inject them into controllers in
entryPoint. Services are injected through a controller's constructor arguments. For example, the above shows a
databaseservice that is injected into
CodecRegistryor setting the default
CORSPolicy. All of this initialization is done in
ApplicationChannelis created for each isolate. When your application receives an HTTP request, the request is passed to one of these instances' entry points. These instances are replicas of one another and it doesn't matter which instance processes the request. This isolate-channel architecture is very similar to running multiple servers that run the same application.
ApplicationChannelinstance has its own set of services that are configured in the same way. This behavior also makes design patterns like connection pooling implicit; instead of a pool of database connections, there is a pool of application channels that each have their own database connection.
entryPointare part of the initialization process of an application channel. Most applications only ever need these two methods. Another method, that is rarely used, is
willStartReceivingRequests(). This method is called after
entryPointhave been executed, and right before your application will start receiving requests.
ApplicationChannelsubclass can implement a static method named
ApplicationChannelinstances are created. Any changes made to
optionswill be available in each
initializeApplicationis executed in the main isolate, whereas each
ApplicationChannelis instantiated in its own isolate. This means that any values stored in
ApplicationOptionsmust be safe to pass across isolates - i.e., they can't contain references to closures.
CodecRegistrydo not share values across isolates, because they use a static property to hold a reference to the repository of codecs. Therefore, they must be set up in
initializeApplicationexactly matches what is shown in these code samples. The analyzer can't help you here, unfortunately.
ApplicationChannelsubclass is most often declared in its own file named
lib/channel.dart. This file must be exported from the application library file. For example, if the application is named
wildfire, the application library file is
lib/wildfire.dart. Here is a sample directory structure:
Futurewith the desired result.
Application<T>object. Because the
conduit servecommand manages creating an
Application<T>instance, your code rarely concerns itself with this type.
Application<T>is the top-level object in a Conduit application; it sets up HTTP listeners and directs requests to
Application<T>itself is just a generic container for
ApplicationChannels; it doesn't do much other than kick everything off.
startmethod will initialize at least one instance of the application's
ApplicationChannel. If something goes wrong during this initialization process, the application will throw an exception and halt starting the server. For example, setting up an invalid route in a
ApplicationChannelsubclass would trigger this type of startup exception.
Application<T>has a number of options that determine how it will listen for HTTP requests, such as which port it is listening on or the SSL certificate it will use. These values are available in the channel's
optionsproperty, an instance of