Implementation:Langgenius Dify Marketplace Contract
| Knowledge Sources | |
|---|---|
| Domains | Frontend, Contract, Marketplace, API |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Defines type-safe API contracts for the Dify marketplace endpoints using oRPC, covering collection listing, collection plugin retrieval, and advanced plugin/bundle search.
Description
This module uses the @orpc/contract library to define three strongly-typed API contracts for the marketplace service. Each contract specifies the HTTP method, route path, input shape, and output shape. The contracts build on a shared base contract configured with inputStructure: 'detailed' that separates query/params/body.
The three contracts are:
collectionsContract-- Lists marketplace collections.- Route:
GET /collections - Input: Optional query parameters including search filters (
CollectionsAndPluginsSearchParams) and pagination (page,page_size). - Output: An object containing an array of
MarketplaceCollectionobjects.
- Route:
collectionPluginsContract-- Retrieves plugins belonging to a specific collection.- Route:
POST /collections/{collectionId}/plugins - Input: A path parameter
collectionId(string) and an optional body withCollectionsAndPluginsSearchParamsfor filtering. - Output: An object containing an array of
Pluginobjects.
- Route:
searchAdvancedContract-- Performs an advanced search for plugins or bundles.- Route:
POST /{kind}/search/advanced - Input: A path parameter
kind(either'plugins'or'bundles') and a body of typeOmit<PluginsSearchParams, 'type'>. - Output: A
PluginsFromMarketplaceResponseobject containing paginated plugin results.
- Route:
These contracts are composed into the marketplaceRouterContract in the router module and used for both client-side type inference and runtime request/response validation.
Usage
These contracts are imported by web/contract/router.ts to build the marketplace router. They are consumed by oRPC client implementations that generate type-safe API call functions. They should not be called directly -- instead use the generated client methods that reference these contracts.
Code Reference
Source Location
- Repository: Langgenius_Dify
- File: web/contract/marketplace.ts
- Lines: 1-57
Signature
import { base } from './base'
export const collectionsContract = base
.route({ path: '/collections', method: 'GET' })
.input(type<{
query?: CollectionsAndPluginsSearchParams & { page?: number, page_size?: number }
}>())
.output(type<{
data?: { collections?: MarketplaceCollection[] }
}>())
export const collectionPluginsContract = base
.route({ path: '/collections/{collectionId}/plugins', method: 'POST' })
.input(type<{
params: { collectionId: string }
body?: CollectionsAndPluginsSearchParams
}>())
.output(type<{
data?: { plugins?: Plugin[] }
}>())
export const searchAdvancedContract = base
.route({ path: '/{kind}/search/advanced', method: 'POST' })
.input(type<{
params: { kind: 'plugins' | 'bundles' }
body: Omit<PluginsSearchParams, 'type'>
}>())
.output(type<{ data: PluginsFromMarketplaceResponse }>())
Import
import {
collectionsContract,
collectionPluginsContract,
searchAdvancedContract,
} from '@/contract/marketplace'
I/O Contract
Inputs
collectionsContract:
| Name | Type | Required | Description |
|---|---|---|---|
| query.page | number |
No | Page number for pagination |
| query.page_size | number |
No | Number of items per page |
| query (search params) | CollectionsAndPluginsSearchParams |
No | Search and filter parameters (category, tags, sort, etc.) |
collectionPluginsContract:
| Name | Type | Required | Description |
|---|---|---|---|
| params.collectionId | string |
Yes | The ID of the collection to fetch plugins for |
| body | CollectionsAndPluginsSearchParams |
No | Search and filter parameters for plugins within the collection |
searchAdvancedContract:
| Name | Type | Required | Description |
|---|---|---|---|
| params.kind | 'bundles' | Yes | Whether to search plugins or bundles |
| body | Omit<PluginsSearchParams, 'type'> |
Yes | Advanced search parameters (query, category, tags, sort, pagination) |
Outputs
collectionsContract:
| Name | Type | Description |
|---|---|---|
| data.collections | MarketplaceCollection[] |
Array of marketplace collection objects |
collectionPluginsContract:
| Name | Type | Description |
|---|---|---|
| data.plugins | Plugin[] |
Array of plugin objects belonging to the collection |
searchAdvancedContract:
| Name | Type | Description |
|---|---|---|
| data | PluginsFromMarketplaceResponse |
Paginated search results with plugin list and metadata |
Usage Examples
// These contracts are typically consumed through the generated oRPC client.
// Example of how they appear in the router contract:
import { collectionsContract, collectionPluginsContract, searchAdvancedContract } from '@/contract/marketplace'
const marketplaceRouterContract = {
collections: collectionsContract,
collectionPlugins: collectionPluginsContract,
searchAdvanced: searchAdvancedContract,
}
// Client usage (via oRPC generated client):
const collections = await marketplaceClient.collections({
query: { page: 1, page_size: 20 },
})
// collections.data?.collections => MarketplaceCollection[]
const plugins = await marketplaceClient.collectionPlugins({
params: { collectionId: 'featured-ai-tools' },
body: { category: 'tool' },
})
// plugins.data?.plugins => Plugin[]
const searchResults = await marketplaceClient.searchAdvanced({
params: { kind: 'plugins' },
body: { query: 'web scraping', sort_by: 'install_count' },
})
// searchResults.data => PluginsFromMarketplaceResponse
Related Pages
- Langgenius_Dify_Contract_Router - Composes this contract into the
marketplaceRouterContract - Langgenius_Dify_Global_Public_Context - System features that control
enable_marketplaceflag