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.
The primary API is GraphQL-based and available at /graphql. This provides a unified interface for all data operations with Discourse.
All GraphQL operations require authentication via JWT token in the Authorization: Bearer <token> header.
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")
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
sourceIdfield - Benefits: Prevents ID collisions and provides stable identifiers
The API uses cursor-based pagination for collections:
- Connection Pattern: Collections return
edgesandpageInfo - Cursors: Base64-encoded pagination tokens
- Arguments:
first(limit) andafter(cursor) parameters - Page Info:
hasNextPageandendCursorfor navigation
Example:
query {
teret(id: "2") {
bytes(first: 20, after: "cursor") {
edges {
cursor
node {
id
title
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}Get the current authenticated user's profile.
query {
me {
id
username
name
avatarTemplate
trustLevel
groups {
id
name
}
}
}Get the latest topics feed.
query {
latestTopics {
topics {
id
title
slug
postsCount
likeCount
views
createdAt
lastPostedAt
categoryId
tags
}
}
}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
}
}
}
}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
}
}
}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
}
}
}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
}
}
}
}Get a specific byte (topic).
query {
byte(id: "123") {
id
sourceId
title
slug
postsCount
likeCount
views
createdAt
lastPostedAt
categoryId
tags
}
}Refresh an access token using a refresh token.
mutation {
refreshToken(refreshToken: "your-refresh-token") {
accessToken
refreshToken
expiresIn
}
}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
}
}Create a new post (reply).
mutation {
createPost(input: {
topicId: "123"
raw: "This is my reply"
replyToPostNumber: 1
}) {
id
postNumber
username
createdAt
cooked
}
}Like a post.
mutation {
likePost(postId: "456")
}Unlike a post.
mutation {
unlikePost(postId: "456")
}Bookmark a post.
mutation {
bookmarkPost(postId: "456")
}Remove bookmark from a post.
mutation {
unbookmarkPost(postId: "456")
}The server also provides REST endpoints for authentication and system operations.
Returns the health status of the server.
Returns the version and environment of the running server.
Returns the JSON Web Key Set (JWKS) for verifying JWT signatures.
Exposes Prometheus-compatible metrics for monitoring.