A 'service' in Anno-J (often referred to as a fetcher) is is a small program that sits out on the web somewhere and responds to simple HTTP requests with sensible data. For example, a time fetcher might respond to the query: http://www.somesite.com/service?tellTime with a response of 09:30:00 AM. From the client's perspective, the fetcher's implementation details are irrelevant.
Anno-J is a client and it's important to realize that it does not store data: it is a REST-based, 100% server-side agnostic application. It is the responsibility of the data provider, not the client, to maintain, curate, secure, syndicate, and host his/her own data.
This section provides an example of how to create a server-side fetcher that provides Gene Model annotation data in response to simple HTTP GET requests (conveniently the same requests that an Anno-J GeneModels plugin uses). The example uses MySQL, PHP and Apache but does not depend upon these technologies.
The first step is to prepare your data so that it can be queried rapidly. You can use any technology to achieve this, but I recommend a SQL server. In this example, MySQL is used and the data in question is for gene models.
Because Anno-J makes requests for data in predictable and discrete frames, it is fairly trivial to build server-side caches that allow the data base to be taken out of the loop. For further efficiency, caches should be stored and streamed in a zipped format.
/** * The first step is to create a table to house gene model annotations. * I favour a format that is similar, but not identical, to GFF. */ CREATE TABLE `browser.genes` ( `id` varchar(11) default NULL, `parent` varchar(11) default NULL, `assembly` char(1), `strand` char(1), `class` tinytext, `start` bigint(20) default NULL, `end` bigint(20) default NULL, `description` text ) ENGINE=MyISAM DEFAULT CHARSET=latin1; /** * Now the table is populated. Here are some data I prepared earlier... */ LOAD DATA INFILE 'my_data' INTO TABLE browser.genes; /** * The table now looks like this: */ mysql> select id, parent, assembly, strand, class, start, end, concat(substring(description,1,20),'...') as info from browser.genes limit 20; +-------------+-------------+----------+--------+-------+-------+-------+-------------------------+ | id | parent | assembly | strand | class | start | end | info | +-------------+-------------+----------+--------+-------+-------+-------+-------------------------+ | f3 | AT1G01010.1 | 1 | + | UTR5 | 3631 | 3759 | NULL | | AT1G01010.1 | NULL | 1 | + | mRNA | 3631 | 5899 | ANAC001 (Arabidopsis... | | f6 | AT1G01010.1 | 1 | + | CDS | 3760 | 3913 | NULL | | f7 | AT1G01010.1 | 1 | + | CDS | 3996 | 4276 | NULL | | f9 | AT1G01010.1 | 1 | + | CDS | 4486 | 4605 | NULL | | f11 | AT1G01010.1 | 1 | + | CDS | 4706 | 5095 | NULL | | f13 | AT1G01010.1 | 1 | + | CDS | 5174 | 5326 | NULL | | f15 | AT1G01010.1 | 1 | + | CDS | 5439 | 5630 | NULL | | f17 | AT1G01010.1 | 1 | + | UTR3 | 5631 | 5899 | NULL | | f19 | AT1G01040.1 | 1 | + | UTR5 | 23146 | 23518 | NULL | | AT1G01040.1 | NULL | 1 | + | mRNA | 23146 | 31227 | DCL1 (DICER-LIKE1); ... | | f22 | AT1G01040.1 | 1 | + | CDS | 23519 | 24451 | NULL | | f23 | AT1G01040.1 | 1 | + | CDS | 24542 | 24655 | NULL | | f25 | AT1G01040.1 | 1 | + | CDS | 24752 | 24962 | NULL | | f27 | AT1G01040.1 | 1 | + | CDS | 25041 | 25435 | NULL | | f29 | AT1G01040.1 | 1 | + | CDS | 25524 | 25743 | NULL | | f31 | AT1G01040.1 | 1 | + | CDS | 25825 | 25997 | NULL | | f33 | AT1G01040.1 | 1 | + | CDS | 26081 | 26203 | NULL | | f35 | AT1G01040.1 | 1 | + | CDS | 26292 | 26452 | NULL | | f37 | AT1G01040.1 | 1 | + | CDS | 26543 | 26776 | NULL | +-------------+-------------+----------+--------+-------+-------+-------+-------------------------+ 20 rows in set (0.00 sec) /** * Finally, an index is added to facilitate faster searching */ ALTER TABLE genes ADD INDEX(assembly, start, end);