DEV Community

Alex Spinov
Alex Spinov

Posted on

Convex Has a Free API You Should Know About

Convex is a reactive backend platform that replaces your database, server functions, and realtime layer — all with TypeScript.

Server Functions

// convex/tasks.ts
import { query, mutation } from './_generated/server'
import { v } from 'convex/values'

export const list = query({
  args: { limit: v.optional(v.number()) },
  handler: async (ctx, args) => {
    return ctx.db
      .query('tasks')
      .order('desc')
      .take(args.limit ?? 10)
  }
})

export const create = mutation({
  args: { text: v.string() },
  handler: async (ctx, args) => {
    return ctx.db.insert('tasks', {
      text: args.text,
      completed: false,
      createdAt: Date.now()
    })
  }
})
Enter fullscreen mode Exit fullscreen mode

Realtime — Automatic

Queries are automatically reactive:

// React component — updates in realtime!
function TaskList() {
  const tasks = useQuery(api.tasks.list, { limit: 20 })
  const createTask = useMutation(api.tasks.create)

  return (
    <div>
      <button onClick={() => createTask({ text: 'New task' })}>
        Add Task
      </button>
      {tasks?.map(task => (
        <div key={task._id}>{task.text}</div>
      ))}
    </div>
  )
}
// When ANY client adds a task, ALL clients see it instantly
Enter fullscreen mode Exit fullscreen mode

HTTP Actions — External API

// convex/http.ts
import { httpRouter } from 'convex/server'
import { httpAction } from './_generated/server'

const http = httpRouter()

http.route({
  path: '/api/webhook',
  method: 'POST',
  handler: httpAction(async (ctx, request) => {
    const body = await request.json()
    await ctx.runMutation(api.tasks.create, { text: body.text })
    return new Response(JSON.stringify({ ok: true }), { status: 200 })
  })
})

export default http
Enter fullscreen mode Exit fullscreen mode

Scheduled Functions (Cron)

// convex/crons.ts
import { cronJobs } from 'convex/server'

const crons = cronJobs()

crons.interval('cleanup old tasks', { hours: 24 }, api.tasks.cleanup)
crons.cron('daily report', '0 9 * * *', api.reports.generateDaily)

export default crons
Enter fullscreen mode Exit fullscreen mode

File Storage

// Generate upload URL
export const generateUploadUrl = mutation(async (ctx) => {
  return await ctx.storage.generateUploadUrl()
})

// Store file reference
export const saveFile = mutation({
  args: { storageId: v.id('_storage'), name: v.string() },
  handler: async (ctx, args) => {
    return ctx.db.insert('files', {
      storageId: args.storageId,
      name: args.name,
      url: await ctx.storage.getUrl(args.storageId)
    })
  }
})
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A team building a collaborative tool was maintaining PostgreSQL + Redis + WebSocket server + cron jobs. They moved to Convex: mutations auto-sync to all clients, scheduled functions replaced cron, and they deleted their entire WebSocket layer. Backend code went from 3000 lines to 800.

Convex is what Firebase promised but never delivered.


Build Smarter Data Pipelines

Need to scrape websites, extract APIs, or automate data collection? Check out my ready-to-use scrapers on Apify — no coding required.

Custom scraping solution? Email me at spinov001@gmail.com — fast turnaround, fair prices.

Top comments (0)