Advanced Tutorial
Let’s continue exploring Agentlang by expanding our blogging application. In this section, we’ll dive into three powerful concepts: relationships, intelligent agents, and authentication. By the end, you’ll see how a simple CRUD service can evolve into a smart, secure application.
Relationships: Connecting Posts, Comments, and Categories
Previously, our blog.core module included just the Post entity:
module blog.core
entity Post {
id UUID @id @default(uuid()),
title String,
content String,
postedBy Email,
createdAt DateTime @default(now())
}Now, let’s make the blog more interactive by allowing users to comment on posts. Comments can be represented as a new entity:
entity Comment {
id UUID @id @default(uuid()),
content String,
postedBy Email,
postedOn DateTime @default(now())
}But how do we associate comments with posts? Agentlang’s relationships let us express these connections naturally. Here, a post is the parent, and its comments are children—a one-to-many hierarchical relationship. We can model this with a contains relationship:
relationship PostComment contains(Post, Comment)Once added, you can start your blog application and attach a comment to an existing post (use a real post ID from your local store):
curl -X POST http://localhost:8080/blog.core/Post/<POST_ID>/PostComment/Comment \
-H 'Content-Type: application/json' \
-d '{"content": "Nice article!", "postedBy": "kk@fractl.io"}'To fetch all comments for a post:
curl -X GET http://localhost:8080/blog.core/Post/<POST_ID>/PostComment/Comment \
-H 'Content-Type: application/json'We can also organize posts by topic. Let’s add a Category entity:
entity Category {
id UUID @id @default(uuid()),
name String
}Since a category can include multiple posts, and a post can belong to multiple categories, we define a many-to-many relationship:
relationship PostCategory between(Post, Category)Add and fetch categories for a post like this:
curl -X POST http://localhost:8080/blog.core/Post/<POST_ID>/PostCategory/Category \
-H 'Content-Type: application/json' \
-d '{"name": "science"}'
curl -X GET http://localhost:8080/blog.core/Post/<POST_ID>/PostCategory/Category \
-H 'Content-Type: application/json'With relationships in place, your blog now has a rich, interconnected structure, supporting comments and categories effortlessly.
Intelligent Agents: Making the Blog Smarter
What if your blog could do more than just store posts? Suppose you want to provide a blog outline and have the post automatically generated. Agentlang makes this possible with agents.
Here’s how to define a simple agent that creates posts based on an outline:
@public agent postEditor {
instruction "Create a new blog post based on the outline provided to you.",
tools [blog.core/Post]
}That’s it! With this one definition, your blog is no longer just a CRUD service — it’s a smart application.
Before running the application, make sure to provide your OpenAI API key:
export OPENAI_API_KEY=<your_openai_api_key>Now you can ask the editor agent to write a post:
curl -X POST http://localhost:8080/blog.core/postEditor \
-H 'Content-Type: application/json' \
-d '{"message": "Write a short introduction to LLMs. Author: me@myblog.org"}'The agent will automatically create a new post using your outline, combining natural language instructions with structured entity creation.
Authentication: Securing Your Blog
So far, anyone could create posts. Let’s add authentication and access control so only authorized users can modify content. For our blog, we’ll enforce these rules:
- Any user can read posts created by others.
- Only the creator of a post can update or delete it.
Add an @rbac annotation to the Post entity to enforce these rules:
entity Post {
id UUID @id @default(uuid()),
title String,
content String,
postedBy Email,
createdAt DateTime @default(now()),
@rbac [(roles: [user], allow: [create, read])]
}Next, update your configuration to enable authentication and RBAC:
{
"store": {"type": "sqlite", "dbname": "blog.db"},
"service": {"port": 8080},
"auth": {"enabled": true},
"rbac": {"enabled": true}
}Agentlang integrates with AWS Cognito as the authentication provider. After setting up a Cognito user pool and adding users to the "user" group, export the required environment variables:
export COGNITO_USER_POOL_ID=<your-pool-id>
export COGNITO_CLIENT_ID=<your-client-id>
export AWS_ACCESS_KEY_ID=<your-aws-access-key>
export AWS_REGION=<your-aws-region>
export AWS_SECRET_ACCESS_KEY=<your-aws-secret-access-key>Finally, obtain an auth token for a user by calling the /login API:
curl -X POST http://localhost:8080/agentlang.auth/login \
-H 'Content-Type: application/json' \
-d '{"email": "user@email.com", "password": "user.password"}'The response includes an id-token, which you can include in subsequent API requests as:
Authorization: Bearer <id-token>With authentication and RBAC in place, your blog is now secure and multi-user aware, while still taking advantage of Agentlang’s intelligent agents and relationships.
Congratulations! You’ve now transformed a simple CRUD service into a feature-rich, intelligent, and secure blog application. From here, you can explore agent reliability modeling or dive deeper into the core concepts of Agentlang to unlock even more advanced capabilities.