graphql-operations
>
Works with
---
name: graphql-operations
description: >
license: MIT
---
# GraphQL Operations Guide
This guide covers best practices for writing GraphQL operations (queries, mutations, subscriptions) as a client developer. Well-written operations are efficient, type-safe, and maintainable.
## Operation Basics
### Query Structure
```graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
```
### Mutation Structure
```graphql
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
}
}
```
### Subscription Structure
```graphql
subscription OnMessageReceived($channelId: ID!) {
messageReceived(channelId: $channelId) {
id
content
sender {
id
name
}
}
}
```
## Quick Reference
### Operation Naming
| Pattern | Example |
| ------------ | ------------------------------------------- |
| Query | `GetUser`, `ListPosts`, `SearchProducts` |
| Mutation | `CreateUser`, `UpdatePost`, `DeleteComment` |
| Subscription | `OnMessageReceived`, `OnUserStatusChanged` |
### Variable Syntax
```graphql
# Required variable
query GetUser($id: ID!) { ... }
# Optional variable with default
query ListPosts($first: Int = 20) { ... }
# Multiple variables
query SearchPosts($query: String!, $status: PostStatus, $first: Int = 10) { ... }
```
### Fragment Syntax
```graphql
# Define fragment
fragment UserBasicInfo on User {
id
name
avatarUrl
}
# Use fragment
query GetUser($id: ID!) {
user(id: $id) {
...UserBasicInfo
email
}
}
```
### Directives
```graphql
query GetUser($id: ID!, $includeEmail: Boolean!) {
user(id: $id) {
id
name
email @include(if: $includeEmail)
}
}
query GetPosts($skipDrafts: Boolean!) {
posts {
id
title
draft @skip(if: $skipDrafts)
}
}
```
## Key Principles
### 1. Request Only What You Need
```graphql
# Good: Specific fields
query GetUserName($id: ID!) {
user(id: $id) {
id
name
}
}
# Avoid: Over-fetching
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
bio
posts {
id
title
content
comments {
id
}
}
followers {
id
name
}
# ... many unused fields
}
}
```
### 2. Name All Operations
```graphql
# Good: Named operation
query GetUserPosts($userId: ID!) {
user(id: $userId) {
posts {
id
title
}
}
}
# Avoid: Anonymous operation
query {
user(id: "123") {
posts {
id
title
}
}
}
```
### 3. Use Variables, Not Inline Values
```graphql
# Good: Variables
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
# Avoid: Hardcoded values
query {
user(id: "123") {
id
name
}
}
```
### 4. Colocate Fragments with Components
```tsx
// UserAvatar.tsx
export const USER_AVATAR_FRAGMENT = gql`
fragment UserAvatar on User {
id
name
avatarUrl
}
`;
function UserAvatar({ user }) {
return <img src={user.avatarUrl} alt={user.name} />;
}
```
## Reference Files
Detailed documentation for specific topics:
- [Queries](references/queries.md) - Query patterns and optimization
- [Mutations](references/mutations.md) - Mutation patterns and error handling
- [Fragments](references/fragments.md) - Fragment organization and reuse
- [Variables](references/variables.md) - Variable usage and types
- [Tooling](references/tooling.md) - Code generation and linting
## Ground Rules
- ALWAYS name your operations (no anonymous queries/mutations)
- ALWAYS use variables for dynamic values
- ALWAYS request only the fields you need
- ALWAYS include `id` field for cacheable types
- NEVER hardcode values in operations
- NEVER duplicate field selections across files
- PREFER fragments for reusable field selections
- PREFER colocating fragments with components
- USE descriptive operation names that reflect purpose
- USE `@include`/`@skip` for conditional fieldsMore API Design skills
lark-event
larksuite/cli
Lark/Feishu real-time event listening / subscribing / consuming: stream events as NDJSON via `lark-cli event consume <EventKey>` (covers IM messages/reactions/chat changes, Approval status changes, Task updates, VC meeting started/joined/ended, Minutes generated, Whiteboard updated, etc.). Use for Lark bots, real-time message processing, long-running subscribers, streaming webhook/push handlers. Supports `--max-events` / `--timeout` bounded runs and a stderr ready-marker contract — designed for AI agents running as subprocesses.
lark-contact
larksuite/cli
飞书 / Lark 通讯录:按姓名 / 邮箱解析成 open_id,或按 open_id 反查姓名 / 部门 / 邮箱 / 联系方式 / 个人状态 / 签名,以及按关键词搜索当前用户可见的机器人 / 智能体(agent)。当用户提到一个名字要下一步发消息 / 排日程,或拿到 open_id 想查具体信息时使用。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。
lark-openapi-explorer
larksuite/cli
飞书/Lark 原生 OpenAPI 探索:从官方文档库中挖掘未经 CLI 封装的原生 OpenAPI 接口。当用户的需求无法被现有 lark-* skill 或 lark-cli 已注册命令满足,需要查找并调用原生飞书 OpenAPI 时使用。

