teodevgroup / teo

Schema-driven web server framework.
https://teodev.io
Apache License 2.0
1.33k stars 43 forks source link
agile agile-development apiserver apiservice code-generation database http http-server language-parser nodejs orm python rust server single-file webdevelopment webframework

Teo



Schema-driven web server framework.

Quickstart   •   Official website   •   Docs   •   Blog   •   Discord

Introduction

Teo is schema-driven web server framework. The server side API is native to Rust, Node.js and Python.

Highlights & Features

Getting started

The fastest way to get started with Teo is by following the Quickstart guide.

Installation

Install Node.js edition.

npm install @teocloud/teo

Install Python edition.

pip install teo

Install Rust edition.

cargo install teo

Write a schema-only server

To write a server is quite simple with Teo. Create a file named schema.teo. Specify which database to connect and which port to listen.

connector {
  provider: .sqlite,
  url: "sqlite::memory:"
}

server {
  bind: ("0.0.0.0", 5050)
}

model User {
  @id @autoIncrement @readonly
  id: Int
  @unique @onSet($if($presents, $isEmail))
  email: String
  name: String?
  @relation(fields: .id, references: .authorId)
  posts: Post[]
}

model Post {
  @id @autoIncrement @readonly
  id: Int
  title: String
  content: String?
  @default(false)
  published: Bool
  @foreignKey
  authorId: Int
  @relation(fields: .authorId, references: .id)
  author: User
}

Start the server with teo serve command. Now you can create, update, delete, read, aggregate and group by. Read our Query client guide for detailed usage.

Write custom handlers

Declare the handler in the schema.

@map(.get, "/echo/:data", interface: "EchoPathArguments")
declare nonapi handler echo(): Any

Implement the handler with program code.

Node.js implementation

import { App, Response, RequestCtx } from '@teocloud/teo'
import { EchoPathArguments } from './entities'

const app = new App()
app.mainNamespace().defineHandler("echo", (ctx: RequestCtx) => {
    const pathArguments: EchoPathArguments = ctx.pathArguments()
    return Response.string(pathArguments.data, "text/plain")
})
app.run()

Python implementation

from asyncio import run
from teo import App, Response, RequestCtx
from entities import EchoPathArguments

async def main():
    app = App()
    def echo_handler(ctx: RequestCtx):
        path_arguments: EchoPathArguments = ctx.path_arguments()
        return Response.string(path_arguments["data"], "text/plain")
    app.main_namespace().define_handler("echo", echo_handler)
    await app.run()

run(main())

Rust implementation

mod entities;

use tokio::main;
use teo::prelude::{App, Response, Result, path};
use crate::entities::EchoPathArguments;

#[main]
async fn main() -> Result<()> {
    let app = App::new()?;
    app.main_namespace().define_handler("echo", |path_args: EchoPathArguments| async move {
        Ok::<Response, Error>(Response::string(path_args.data(), "text/plain"))
    });
    app.run().await
}

Tutorials

We prepared a Beginner tutorial series to help you learn and understand Teo.

Issues

Welcome to submit issues in this repo.

Contributing

Read our Contributing guide to set projects up and start contributing.

License

TEO is under Apache 2.0 license.