Skip to main content
Version: v3.x (DDN)

Extend a Model

Introduction

In this tutorial, you'll learn how to extend an existing field on a model to enhance its functionality. We'll demonstrate this using PostgreSQL as the data source, but the steps apply to any data source supported by Hasura DDN. By the end, you'll have created a relationship that integrates custom logic with your API. This process will show you how to:

  • Initialize a DDN project and connect to a data source.
  • Add a model to your metadata from a database table.
  • Create and implement custom logic in a lambda connector.
  • Establish relationships between models and custom commands.

This tutorial should take about ten minutes.

Step 1. Initialize a new local DDN project

Create a new project using the DDN CLI:
ddn supergraph init lambda-tutorial

Step 2. Prepare the PostgreSQL data

In your project directory, run:
ddn connector init my_pg -i

From the dropdown, start typing PostgreSQL and hit enter to advance through all the options.

The CLI will output something similar to this:

HINT To access the local Postgres database:
- Run: docker compose -f app/connector/my_pg/compose.postgres-adminer.yaml up -d
- Open Adminer in your browser at http://localhost:5143 and create tables
- To connect to the database using other clients use postgresql://user:[email protected]:8105/dev
Use the hint from the CLI output:
docker compose -f app/connector/my_pg/compose.postgres-adminer.yaml up -d

Run docker ps to see on which port Adminer is running. Then, you can navigate to the address below to access it:

http://localhost:<ADMINER_PORT>
Next, via Adminer select SQL command from the left-hand nav, then enter the following:
--- Create the table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
age INT NOT NULL
);

--- Insert some data
INSERT INTO users (name, age) VALUES ('Alice', 25);
INSERT INTO users (name, age) VALUES ('Bob', 30);
INSERT INTO users (name, age) VALUES ('Charlie', 35);

You can verify this worked by using Adminer to query all records from the users table:

SELECT * FROM users;
Next, use the CLI to introspect your PostgreSQL database:
ddn connector introspect my_pg
Now, track the table from your PostgreSQL database as a model in your DDN metadata:
ddn models add my_pg users

Open the app/metadata directory and you'll find a newly-generated file: Users.hml. The DDN CLI will use this Hasura Metadata Language file to represent the users table from PostgreSQL in your API as a model.

Step 3. Initialize the lambda connector

Run the following command:
ddn connector init my_ts -i
  • Select hasura/nodejs from the list of connectors.
  • Choose a port (press enter to accept the default recommended by the CLI).

If you open the app/connector/my_ts directory, you'll see the functions.ts file generated by the CLI; this will be the entrypoint for your connector.

Step 4. Add your custom logic

From the connector directory, install the necessary packages:
cd app/connector/my_ts && npm install
Then, replace the contents of functions.ts with the following:
/**
* @readonly
*/
export function shoutName(name: string) {
return `${name.toUpperCase()}`;
}

Step 5. Introspect your lambda connector

Introspect the connector:
ddn connector introspect my_ts
Then, we can generate a metadata file for each function using the following command:
# alternatively, use ddn command add my_ts "*" for bulk adds
ddn command add my_ts shoutName

Step 6. Create a relationship

In Users.hml, add the following Relationship object:
---
kind: Relationship
version: v1
definition:
name: shoutName # Define a name to expose in the supergraph API
sourceType: Users # The existing source object type (which also defines the source model Users)
target:
command: # The target is a command
name: ShoutName # The name of the existing command we have defined in metadata
subgraph: app # The existing subgraph the command is defined in
mapping:
- source:
fieldPath:
- fieldName: name # The field on the source object type that we want to provide to the target command as an argument
target:
argument:
argumentName: name # The name of the argument on the target command that we want to map to the source field

Step 7. Create a new build and test

Create a new build:
ddn supergraph build local
Start your services:
ddn run docker-start
Open your local console:
ddn console --local
Using the GraphiQL explorer, you can now use shout() as a field on the Users model:
query UsersWithShoutedName {
users {
id
name
shoutName
}
}

Next steps

Now that you know how to extend your existing data sources using custom business logic, check out our advanced use cases in this section: