conduit serve
or dart bin/main.script
in a Conduit project directory. Either way, a number of threads are created and your ApplicationChannel
subclass is instantiated on each thread. The channel subclass initializes application behavior which is often the following:Router
-> Authorizer
-> UserController
. Because the router is returned from this method, it handles all incoming requests. It will pass a request to an Authorizer
when the request path is /users
, which will then pass that request to a UserController
if 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.ApplicationChannel.prepare
.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 database
service that is injected into UserController
.CodecRegistry
or setting the default CORSPolicy
. All of this initialization is done in prepare()
.ApplicationChannel
is 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.ApplicationChannel
instance 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.prepare()
and entryPoint
are 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 prepare()
and entryPoint
have been executed, and right before your application will start receiving requests.ApplicationChannel
subclass can implement a static method named initializeApplication()
.ApplicationChannel
instances are created. Any changes made to options
will be available in each ApplicationChannel
's options
property.initializeApplication
is executed in the main isolate, whereas each ApplicationChannel
is instantiated in its own isolate. This means that any values stored in ApplicationOptions
must be safe to pass across isolates - i.e., they can't contain references to closures.CodecRegistry
do 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 ApplicationChannel.prepare()
.initializeApplication
exactly matches what is shown in these code samples. The analyzer can't help you here, unfortunately.ApplicationChannel
subclass 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:Future
with the desired result.Application<T>
object. Because the conduit serve
command 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 ApplicationChannel
s. The Application<T>
itself is just a generic container for ApplicationChannel
s; it doesn't do much other than kick everything off.start
method 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 ApplicationChannel
subclass 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 options
property, an instance of ApplicationOptions
.