Skip to content

Latest commit

 

History

History
367 lines (310 loc) · 5.64 KB

API.md

File metadata and controls

367 lines (310 loc) · 5.64 KB

Fomio BFF Server API Documentation

This document provides an overview of the Fomio BFF server API endpoints. The server provides both REST endpoints for authentication and a GraphQL API for data operations.

GraphQL API

The primary API is GraphQL-based and available at /graphql. This provides a unified interface for all data operations with Discourse.

Authentication

All GraphQL operations require authentication via JWT token in the Authorization: Bearer <token> header.

Schema Overview

The GraphQL schema includes the following types:

  • User: Discourse user profile information
  • Topic: Discourse topics with posts
  • Post: Individual posts within topics
  • Hub: Discourse categories (mapped to "hubs")
  • Teret: Discourse subcategories (mapped to "terets")
  • Byte: Individual topics within categories (mapped to "bytes")

ID System

The API uses opaque IDs to abstract Discourse's internal IDs:

  • Opaque IDs: Base64-encoded strings in the format Type:sourceId (e.g., Hub:123)
  • Source IDs: The original Discourse IDs are available in the sourceId field
  • Benefits: Prevents ID collisions and provides stable identifiers

Pagination

The API uses cursor-based pagination for collections:

  • Connection Pattern: Collections return edges and pageInfo
  • Cursors: Base64-encoded pagination tokens
  • Arguments: first (limit) and after (cursor) parameters
  • Page Info: hasNextPage and endCursor for navigation

Example:

query {
  teret(id: "2") {
    bytes(first: 20, after: "cursor") {
      edges {
        cursor
        node {
          id
          title
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

Queries

me

Get the current authenticated user's profile.

query {
  me {
    id
    username
    name
    avatarTemplate
    trustLevel
    groups {
      id
      name
    }
  }
}

latestTopics

Get the latest topics feed.

query {
  latestTopics {
    topics {
      id
      title
      slug
      postsCount
      likeCount
      views
      createdAt
      lastPostedAt
      categoryId
      tags
    }
  }
}

topic(id: ID!)

Get a specific topic with its posts.

query {
  topic(id: "123") {
    id
    title
    slug
    postsCount
    likeCount
    views
    createdAt
    lastPostedAt
    categoryId
    tags
    postStream {
      posts {
        id
        postNumber
        username
        createdAt
        cooked
        likeCount
      }
    }
  }
}

hubs

Get all hubs (categories).

query {
  hubs {
    id
    sourceId
    name
    slug
    description
    color
    textColor
    topicCount
    postCount
    position
    parentCategoryId
    terets {
      id
      sourceId
      name
      slug
      description
      color
      textColor
      parentCategoryId
    }
  }
}

hub(id: ID!)

Get a specific hub.

query {
  hub(id: "1") {
    id
    sourceId
    name
    slug
    description
    color
    textColor
    topicCount
    postCount
    position
    parentCategoryId
    terets {
      id
      sourceId
      name
      slug
      description
      color
      textColor
      parentCategoryId
    }
  }
}

teret(id: ID!)

Get a specific teret (subcategory) with paginated bytes.

query {
  teret(id: "2") {
    id
    sourceId
    name
    slug
    description
    color
    textColor
    parentCategoryId
    bytes(first: 20, after: "cursor") {
      edges {
        cursor
        node {
          id
          sourceId
          title
          slug
          postsCount
          likeCount
          views
          createdAt
          categoryId
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

byte(id: ID!)

Get a specific byte (topic).

query {
  byte(id: "123") {
    id
    sourceId
    title
    slug
    postsCount
    likeCount
    views
    createdAt
    lastPostedAt
    categoryId
    tags
  }
}

Mutations

refreshToken(refreshToken: String!)

Refresh an access token using a refresh token.

mutation {
  refreshToken(refreshToken: "your-refresh-token") {
    accessToken
    refreshToken
    expiresIn
  }
}

createTopic(input: CreateTopicInput!)

Create a new topic.

mutation {
  createTopic(input: {
    title: "My New Topic"
    raw: "This is the content of my topic"
    categoryId: 1
    tags: ["tag1", "tag2"]
  }) {
    id
    title
    slug
    postsCount
    createdAt
  }
}

createPost(input: CreatePostInput!)

Create a new post (reply).

mutation {
  createPost(input: {
    topicId: "123"
    raw: "This is my reply"
    replyToPostNumber: 1
  }) {
    id
    postNumber
    username
    createdAt
    cooked
  }
}

likePost(postId: ID!)

Like a post.

mutation {
  likePost(postId: "456")
}

unlikePost(postId: ID!)

Unlike a post.

mutation {
  unlikePost(postId: "456")
}

bookmarkPost(postId: ID!)

Bookmark a post.

mutation {
  bookmarkPost(postId: "456")
}

unbookmarkPost(postId: ID!)

Remove bookmark from a post.

mutation {
  unbookmarkPost(postId: "456")
}

REST API

The server also provides REST endpoints for authentication and system operations.

System

GET /health

Returns the health status of the server.

GET /version

Returns the version and environment of the running server.

GET /.well-known/jwks.json

Returns the JSON Web Key Set (JWKS) for verifying JWT signatures.

GET /metrics

Exposes Prometheus-compatible metrics for monitoring.