Modus automatically creates an external API based on the endpoints defined in your app manifest. Modus generates the API signature based on the functions you export from your app.

Exporting functions

Modus uses the default conventions for each language.
Functions written in Go use starting capital letters to expose functions as public. Modus creates an external API for public functions from any file that belongs to the main package.The functions below generate an API endpoint with the signature
type Query {
  classifyText(text: String!, threshold: Float!): String!
}
Since the classify function isnโ€™t capitalized, Modus doesnโ€™t include it in the generated GraphQL API.
package main

import (
  "errors"
  "fmt"
  "github.com/hypermodeinc/modus/sdk/go/models"
  "github.com/hypermodeinc/modus/sdk/go/models/experimental"
)

const modelName = "my-classifier"

// this function takes input text and a probability threshold, and returns the
// classification label determined by the model, if the confidence is above the
// threshold; otherwise, it returns an empty string

func ClassifyText(text string, threshold float32) (string, error) {
  predictions, err:= classify(text)
  if err != nil {
    return "", err
  }

  prediction := predictions[0]
  if prediction.Confidence < threshold {
    return "", nil
  }

  return prediction.Label, nil
}

func classify(texts ...string) ([]experimental.ClassifierResult, error) {
  model, err := models.GetModel[experimental.ClassificationModel](modelName)
  if err != nil {
    return nil, err
  }

  input, err := model.CreateInput(texts...)
  if err != nil {
    return nil, err
  }

  output, err := model.Invoke(input)
  if err != nil {
    return nil, err
  }

  if len(output.Predictions) != len(texts) {
    word := "prediction"
    if len(texts) > 1 {
      word += "s"
    }

    return nil, fmt.Errorf("expected %d %s, got %d", len(texts), word, len(output.Predictions))
  }

  return output.Predictions, nil
}

Generating mutations

By default, all exported functions are generated as GraphQL queries unless they follow specific naming conventions that indicate they perform mutations (data modifications). Functions are automatically classified as mutations when they start with these prefixes:
  • mutate
  • post, patch, put, delete
  • add, update, insert, upsert
  • create, edit, save, remove, alter, modify
  • start, stop
For example:
  • getUserById โ†’ Query
  • listProducts โ†’ Query
  • addUser โ†’ Mutation
  • updateProduct โ†’ Mutation
  • deleteOrder โ†’ Mutation
The prefix is detected precisely - addPost becomes a mutation, but additionalPosts remains a query since โ€œadditionalโ€ doesnโ€™t match the exact โ€œaddโ€ prefix pattern.