Skip to main content

Data Service Quickstart

Get up and running with the Taruvi Data Service in minutes. This guide walks you through creating a complete blog application from scratch.

What You'll Build

A simple blog with:

  • 👤 Users: Author accounts
  • 📝 Posts: Blog articles
  • 💬 Comments: User comments on posts
  • 🏷️ Tags: Post categorization

Prerequisites

  • ✅ Taruvi account with API access
  • ✅ JWT authentication token
  • ✅ Basic understanding of REST APIs
  • ✅ curl, Postman, or similar HTTP client

Step 1: Create Your App

First, create an app to hold your blog data:

curl -X POST https://your-domain.com/api/apps/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Blog",
"description": "A simple blogging platform"
}'

Response:

{
"id": 1,
"name": "My Blog",
"slug": "my-blog",
"description": "A simple blogging platform",
"created_at": "2024-01-15T10:30:00Z"
}

Save the slug value (my-blog) - you'll use it in all future requests.

Step 2: Import Your Schema

Create a file called blog-schema.json with your complete database schema:

{
"name": "blog-schema",
"title": "Blog Database Schema",
"description": "Complete blog application schema",
"resources": [
{
"name": "users",
"title": "User Accounts",
"schema": {
"fields": [
{
"name": "id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "username",
"type": "string",
"constraints": {"required": true, "maxLength": 50}
},
{
"name": "email",
"type": "string",
"format": "email",
"constraints": {"required": true}
},
{
"name": "bio",
"type": "string"
},
{
"name": "created_at",
"type": "datetime"
}
],
"primaryKey": ["id"]
}
},
{
"name": "posts",
"title": "Blog Posts",
"schema": {
"fields": [
{
"name": "id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "author_id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "title",
"type": "string",
"constraints": {"required": true, "maxLength": 200}
},
{
"name": "content",
"type": "string",
"constraints": {"required": true}
},
{
"name": "excerpt",
"type": "string"
},
{
"name": "published_at",
"type": "datetime"
},
{
"name": "status",
"type": "string",
"constraints": {
"required": true,
"enum": ["draft", "published", "archived"]
}
}
],
"primaryKey": ["id"],
"foreignKeys": [
{
"fields": ["author_id"],
"reference": {
"resource": "users",
"fields": ["id"]
}
}
]
}
},
{
"name": "comments",
"title": "Post Comments",
"schema": {
"fields": [
{
"name": "id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "post_id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "user_id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "content",
"type": "string",
"constraints": {"required": true}
},
{
"name": "created_at",
"type": "datetime"
}
],
"primaryKey": ["id"],
"foreignKeys": [
{
"fields": ["post_id"],
"reference": {
"resource": "posts",
"fields": ["id"]
}
},
{
"fields": ["user_id"],
"reference": {
"resource": "users",
"fields": ["id"]
}
}
]
}
},
{
"name": "tags",
"title": "Post Tags",
"schema": {
"fields": [
{
"name": "id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "name",
"type": "string",
"constraints": {"required": true, "maxLength": 50}
},
{
"name": "slug",
"type": "string",
"constraints": {"required": true, "maxLength": 50}
}
],
"primaryKey": ["id"]
}
},
{
"name": "post_tags",
"title": "Post-Tag Relationships",
"schema": {
"fields": [
{
"name": "post_id",
"type": "integer",
"constraints": {"required": true}
},
{
"name": "tag_id",
"type": "integer",
"constraints": {"required": true}
}
],
"primaryKey": ["post_id", "tag_id"],
"foreignKeys": [
{
"fields": ["post_id"],
"reference": {
"resource": "posts",
"fields": ["id"]
}
},
{
"fields": ["tag_id"],
"reference": {
"resource": "tags",
"fields": ["id"]
}
}
]
}
}
]
}

Now import it with automatic table creation:

curl -X POST "https://your-domain.com/api/apps/my-blog/datatables/create_schema/?materialize=true" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d @blog-schema.json

Response:

{
"created_count": 5,
"error_count": 0,
"created_tables": [
{"id": 1, "name": "users", "is_materialized": true, "field_count": 5},
{"id": 2, "name": "posts", "is_materialized": true, "field_count": 7},
{"id": 3, "name": "comments", "is_materialized": true, "field_count": 5},
{"id": 4, "name": "tags", "is_materialized": true, "field_count": 3},
{"id": 5, "name": "post_tags", "is_materialized": true, "field_count": 2}
],
"errors": [],
"materialized": true
}

✅ All 5 tables created and ready to use!

Step 3: Create Some Users

curl -X POST https://your-domain.com/api/apps/my-blog/datatables/users/data/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"bio": "Software developer and tech blogger",
"created_at": "2024-01-15T10:00:00Z"
},
{
"id": 2,
"username": "jane_smith",
"email": "jane@example.com",
"bio": "Product designer and UX enthusiast",
"created_at": "2024-01-16T09:30:00Z"
}
]'

Step 4: Create Blog Posts

curl -X POST https://your-domain.com/api/apps/my-blog/datatables/posts/data/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"id": 1,
"author_id": 1,
"title": "Getting Started with Taruvi",
"content": "In this post, we will explore the powerful features of Taruvi...",
"excerpt": "Learn the basics of Taruvi Data Service",
"status": "published",
"published_at": "2024-01-15T12:00:00Z"
},
{
"id": 2,
"author_id": 1,
"title": "Advanced Querying Techniques",
"content": "Taruvi provides powerful query capabilities including...",
"excerpt": "Master advanced filtering and population",
"status": "published",
"published_at": "2024-01-16T14:00:00Z"
},
{
"id": 3,
"author_id": 2,
"title": "Designing Data-Driven UIs",
"content": "When building interfaces powered by Taruvi...",
"excerpt": "Best practices for UI design",
"status": "draft",
"published_at": null
}
]'

Step 5: Add Some Comments

curl -X POST https://your-domain.com/api/apps/my-blog/datatables/comments/data/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"id": 1,
"post_id": 1,
"user_id": 2,
"content": "Great introduction! Very helpful for beginners.",
"created_at": "2024-01-15T14:20:00Z"
},
{
"id": 2,
"post_id": 1,
"user_id": 1,
"content": "Thanks! Glad you found it useful.",
"created_at": "2024-01-15T15:30:00Z"
},
{
"id": 3,
"post_id": 2,
"user_id": 2,
"content": "The populate feature is amazing!",
"created_at": "2024-01-16T16:00:00Z"
}
]'

Step 6: Query Your Data

List All Published Posts

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?status=published" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Posts with Authors

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?populate=author" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

{
"data": [
{
"id": 1,
"author_id": 1,
"title": "Getting Started with Taruvi",
"status": "published",
"author": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"bio": "Software developer and tech blogger"
}
},
{
"id": 2,
"author_id": 1,
"title": "Advanced Querying Techniques",
"status": "published",
"author": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"bio": "Software developer and tech blogger"
}
}
],
"total": 2
}

Get Single Post with Full Details

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/1/?populate=author,comments.user" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

{
"data": {
"id": 1,
"title": "Getting Started with Taruvi",
"content": "In this post, we will explore...",
"excerpt": "Learn the basics of Taruvi Data Service",
"status": "published",
"published_at": "2024-01-15T12:00:00Z",
"author": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"bio": "Software developer and tech blogger"
},
"comments": [
{
"id": 1,
"content": "Great introduction! Very helpful for beginners.",
"created_at": "2024-01-15T14:20:00Z",
"user": {
"id": 2,
"username": "jane_smith",
"email": "jane@example.com"
}
},
{
"id": 2,
"content": "Thanks! Glad you found it useful.",
"created_at": "2024-01-15T15:30:00Z",
"user": {
"id": 1,
"username": "john_doe",
"email": "john@example.com"
}
}
]
}
}

Search Posts

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?title_contains=taruvi&status=published" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Get User's Posts

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?author_id=1&_sort=published_at&_order=desc" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Paginate Results

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?status=published&_start=0&_end=10" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Step 7: Update Data

Update a Post

curl -X PATCH https://your-domain.com/api/apps/my-blog/datatables/posts/data/3/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "published",
"published_at": "2024-01-17T10:00:00Z"
}'

Update a User's Bio

curl -X PATCH https://your-domain.com/api/apps/my-blog/datatables/users/data/1/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bio": "Senior software developer and technical writer"
}'

Step 8: Delete Data

Delete a Comment

curl -X DELETE https://your-domain.com/api/apps/my-blog/datatables/comments/data/3/ \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Common Patterns

Blog Homepage

Show recent published posts with authors:

curl "https://your-domain.com/api/apps/my-blog/datatables/posts/data/?\
status=published&\
populate=author&\
_sort=published_at&\
_order=desc&\
_start=0&\
_end=10" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Author Profile

Get author with their posts:

curl "https://your-domain.com/api/apps/my-blog/datatables/users/data/1/?\
populate=posts&\
posts_status=published&\
posts_sort=published_at&\
posts_order=desc" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Comment Count

Get total comments for monitoring:

curl "https://your-domain.com/api/apps/my-blog/datatables/comments/data/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" | jq '.total'

The response will include the total count:

{
"data": [...],
"total": 15
}

Next Steps

Learn More

Build Something Real

Now that you've mastered the basics, try building:

  1. E-commerce Store: Products, orders, customers, reviews
  2. Project Management: Projects, tasks, users, comments
  3. CRM: Contacts, companies, deals, activities
  4. Social Network: Users, posts, follows, likes

Integration Examples

Check out our example integrations:

  • React + TypeScript: Full-stack blog application
  • Vue.js: E-commerce storefront
  • Python Backend: Data aggregation service
  • Mobile (React Native): Blog reader app

Troubleshooting

"Method POST not allowed"

Problem: Trying to create data at wrong endpoint

Solution: Add /data/ to the URL:

# ❌ Wrong
POST /api/apps/my-blog/datatables/posts/

# ✅ Correct
POST /api/apps/my-blog/datatables/posts/data/

"Table is not materialized"

Problem: Trying to insert data into unmaterialized table

Solution: Use ?materialize=true when importing schema, or materialize individually:

POST /api/apps/my-blog/datatables/posts/materialize/

Authentication Errors

Problem: Getting 401 Unauthorized

Solution: Check your JWT token:

# Get a new token
POST /api/auth/jwt/token/
{
"username": "your-username",
"password": "your-password"
}

Get Help

Happy coding! 🚀