Defining Modules
Defining a Deno module comes in two parts:
- declaration of queries and mutations in an exo file
- implementation of the module in a TypeScript or JavaScript file
Declaring a module
You may use the @deno
annotation to define a module implemented in TypeScript or JavaScript. The annotation takes a single parameter: the TypeScript or JavaScript file path.
Here is an example of a simple module implemented in TypeScript.
@deno("math.ts")
module MathModule {
@access(true)
query add(a: Int, b: Int): Int
@access(true)
query square(a: Int): Int
}
The @deno
annotation of the MathModule
module specifies that the module implementation is in the math.ts
file. The module declares two queries: add
and square
. The add
query takes two Int
arguments and returns an Int
value. The square
query takes a single Int
argument and returns an Int
value.
Note the @access
annotation on the queries. It specifies that the query is accessible to all users (by default, queries and mutations aren't accessible to anyone). You can specify a fine-grained access control using the @access
annotation, as we will see later.
Implementing a module in TypeScript
For each declared query (or mutation), the corresponding TypeScript code must export a function that matches the query name. Each function must take the same arguments as the query, with each argument's type appropriately mapped to the corresponding TypeScript type. For example, if an argument or return type is Int
, the TypeScript type would be number
. The function must return a value that matches the return type of the query.
We don't need here, but the functions may be declared async
and return a Promise
if they need to perform asynchronous operations. We will explore this in more detail in the next sections.
export function add(a: number, b: number): number {
return a + b;
}
export function square(a: number): number {
return a * a;
}
When you run exo dev
(or exo yolo
), Exograph will generate a starter TypeScript file if it doesn't already exist. Exograph doesn't update the file if it already exists, so you must manually do so.
Once you have the above code, you can run exo dev
. You can then run the add
query in GraphQL Playground:
query {
add(a: 2, b: 3)
}
which should return:
{
"data": {
"add": 5
}
}
Similarly, you can run the square
query:
query {
square(a: 2)
}
which should return:
{
"data": {
"square": 4
}
}
Implementing a module in JavaScript
If you choose to use JavaScript instead of TypeScript, you need to change the name of the file to math.js
:
@deno("math.js")
module MathModule {
@access(true)
query add(a: Int, b: Int): Int
@access(true)
query square(a: Int): Int
}
The math.js
file looks pretty much the same as the TypeScript file, except that you don't need to specify the type of the arguments or the return value.
export function add(a, b) {
return a + b;
}
export function square(a) {
return a * a;
}
You can now execute the same queries as before.