Agent Skillswebiny/webiny-js › webiny-full-stack-architect

webiny-full-stack-architect

GitHub

提供Webiny全栈扩展的骨架结构与注册模式,涵盖API与Admin入口、共享领域层及包结构规范,指导开发人员在extensions或packages中正确构建和注册全栈功能模块。

skills/user-skills/full-stack-architect/SKILL.md webiny/webiny-js

Trigger Scenarios

创建同时包含API和Admin功能的Webiny扩展 需要遵循特定架构模式注册全栈组件时

Install

npx skills add webiny/webiny-js --skill webiny-full-stack-architect -g -y
More Options

Non-standard path

npx skills add https://github.com/webiny/webiny-js/tree/next/skills/user-skills/full-stack-architect -g -y

Use without installing

npx skills use webiny/webiny-js@webiny-full-stack-architect

指定 Agent (Claude Code)

npx skills add webiny/webiny-js --skill webiny-full-stack-architect -a claude-code -g -y

安装 repo 全部 skill

npx skills add webiny/webiny-js --all -g -y

预览 repo 内 skill

npx skills add webiny/webiny-js --list

SKILL.md

Frontmatter
{
    "name": "webiny-full-stack-architect",
    "description": "Full-stack extension skeleton and registration pattern. Use this skill when creating an extension that spans both API and Admin — the top-level component with Api.Extension and Admin.Extension entry points, shared domain layer, BuildParam declarations, and package structure. References webiny-api-architect and webiny-admin-architect for layer-specific details."
}

Full-Stack Extension Skeleton

TL;DR

A full-stack extension bundles API and Admin into a single package with a shared domain layer. The top-level component registers both sides via <Api.Extension> and <Admin.Extension>, which point to separate entry-point files. Each side follows its own layered architecture pattern — see webiny-api-architect and webiny-admin-architect skills for details.

Working Context

This skill applies to both extension developers (working in extensions/) and core developers (working in packages/). The architecture patterns are the same — only the import convention and registration mechanism differ.

Extensions (extensions/) Core (packages/)
Imports webiny/api, webiny/admin, webiny/admin/ui @webiny/feature/api, @webiny/app-admin, @webiny/admin-ui
Catalog paths Use the Import: path Use the Source: path
Registration <Api.Extension src={...}> / <Admin.Extension src={...}> in webiny.config.tsx createFeature registered directly by the package's module initializer
Entry point export Files targeted by Extension src MUST use export default No restriction — features are registered programmatically
Top-level component Required — composes <Api.Extension> + <Admin.Extension> Not applicable — each package registers its own features

Detect which context you're in by checking the file path: extensions/ → extension mode, packages/ → core mode.

RULE — Extension Entry Points

Admin extensions CANNOT be directly mounted in webiny.config.tsx or in any child component tree without going through <Admin.Extension />.

The same rule applies to API extensions — they must go through <Api.Extension />.

These entry-point components are the only way to register code that runs inside the Admin app or the API runtime. They use the src prop to point to a file that will be loaded in the correct execution environment (browser for Admin, Lambda for API). Bypassing these entry points will fail at runtime because the Admin and API contexts (DI containers, routers, GraphQL registries, etc.) are not available outside their respective runtimes.

YOU MUST include the full file path with the .ts or .tsx extension in every src prop. For example, use src={"/extensions/lead/src/index.ts"}, NOT src={"/extensions/lead"}. Omitting the file extension will cause a build failure.

YOU MUST use export default for the createImplementation() call when the file is targeted directly by an Extension src prop. Using a named export (export const Foo = SomeFactory.createImplementation(...)) will cause a build failure. Named exports are only valid inside files registered via createFeature.

// CORRECT — always use entry-point components
<Api.Extension src={import.meta.dirname + "/api/Extension.js"} />
<Admin.Extension src={import.meta.dirname + "/admin/Extension.js"} />

// WRONG — never mount admin/api code directly
<MyAdminComponent />     // Will not have access to Admin DI container
<MyApiFeature />         // Will not have access to API DI container

Package Structure

my-extension/
├── src/
│   ├── index.ts                  # Single public export
│   ├── MyExtension.tsx           # Top-level component (registers Api + Admin)
│   ├── shared/                   # Shared between API and Admin
│   │   ├── constants.ts          # Model IDs, permission names, etc.
│   │   └── types.ts              # Shared types
│   ├── api/                      # API-side code → see webiny-api-architect skill
│   │   ├── Extension.ts
│   │   ├── domain/
│   │   ├── features/
│   │   └── graphql/
│   └── admin/                    # Admin-side code → see webiny-admin-architect skill
│       ├── Extension.tsx
│       ├── features/
│       └── presentation/

Top-Level Component

The top-level component is the single entry point that consumers use. It registers both the API and Admin extensions:

// src/MyExtension.tsx
import React from "react";
import { Api, Admin } from "webiny/extensions";

export const MyExtension = () => {
  return (
    <>
      {/* API extensions — runs in Lambda */}
      <Api.Extension src={import.meta.dirname + "/api/Extension.js"} />

      {/* Admin extensions — runs in browser */}
      <Admin.Extension src={import.meta.dirname + "/admin/Extension.js"} />
    </>
  );
};

Conditional rendering can wrap the entry points (e.g., feature flags, config parameters):

<Infra.Env.Is name={"prod"}>
  <Api.Extension src={import.meta.dirname + "/api/Extension.js"} />
  <Admin.Extension src={import.meta.dirname + "/admin/Extension.js"} />
</Infra.Env.Is>

Shared Domain Layer

The shared/ directory contains types and value objects used by both API and Admin:

// src/shared/constants.ts
export const MY_MODEL_ID = "myModel";

// src/shared/MyEntity.ts
export interface MyEntityValues {
  name: string;
  status: "active" | "inactive";
}

export interface MyEntityDto {
  id: string;
  values: MyEntityValues;
}

export class MyEntity {
  private constructor(private dto: MyEntityDto) {}

  static from(dto: MyEntityDto) {
    return new MyEntity(dto);
  }

  get id() {
    return this.dto.id;
  }

  get values() {
    return this.dto.values;
  }
}

Build Parameters

Build parameters pass configuration from webiny.config.tsx (build time) into both the API runtime and the Admin app. A deployed API must NEVER use process.env to read configuration.

BuildParam declarations MUST live inside the extension's top-level component, NOT in webiny.config.tsx. Required parameters are exposed as React props on the extension component.

Declaring BuildParams

// src/MyExtension.tsx — declares build params as React props
interface MyExtensionProps {
  apiEndpoint: string;
  dashboardUrl: string;
}

export const MyExtension = ({ apiEndpoint, dashboardUrl }: MyExtensionProps) => {
  return (
    <>
      <Api.BuildParam paramName="MY_API_ENDPOINT" value={apiEndpoint} />
      <Admin.BuildParam paramName="DASHBOARD_URL" value={dashboardUrl} />

      <Api.Extension src={import.meta.dirname + "/api/Extension.js"} />
      <Admin.Extension src={import.meta.dirname + "/admin/Extension.js"} />
    </>
  );
};

Consuming in webiny.config.tsx

// webiny.config.tsx — the ONLY place where process.env is read
<MyExtension
  apiEndpoint={process.env.MY_API_ENDPOINT || ""}
  dashboardUrl={process.env.DASHBOARD_URL || ""}
/>

Reading BuildParams

  • API side: Inject BuildParams via DI — see webiny-api-architect skill
  • Admin side: Use useBuildParams() hook — see webiny-admin-architect skill

Checklist

  1. Create top-level component that uses <Api.Extension> and <Admin.Extension> — never mount admin/api code directly
  2. Put shared domain models and constants in shared/
  3. Declare <Api.BuildParam> / <Admin.BuildParam> in the top-level component, not in webiny.config.tsx
  4. API entry point uses createFeature with register(container) — see webiny-api-architect
  5. Admin entry point is a React component with <RegisterFeature> — see webiny-admin-architect
  6. Use .js extensions in all import paths (ESM modules)

Quick Reference

Entry point:            <Api.Extension src={...} /> + <Admin.Extension src={...} />
Shared code:            shared/ directory for domain models, constants, types
API architecture:       → see webiny-api-architect skill
Admin architecture:     → see webiny-admin-architect skill
DI pattern:             → see webiny-dependency-injection skill
BuildParam declare:     <Api.BuildParam paramName="KEY" value={prop} />
                        <Admin.BuildParam paramName="KEY" value={prop} />
BuildParam read (API):  buildParams.get<T>("KEY") via DI (→ webiny-api-architect)
BuildParam read (Admin): useBuildParams().get<T>("KEY") (→ webiny-admin-architect)
Import extensions:      Always use .js extensions in import paths (ESM)

Related Skills

  • webiny-api-architect — API-side architecture (features, abstractions, container registration)
  • webiny-admin-architect — Admin-side architecture (headless + presentation features)
  • webiny-project-structure — Extension registration and webiny.config.tsx
  • webiny-dependency-injection — The createImplementation DI pattern and injectable services

Version History

  • 80eb1c5 Current 2026-08-20 10:07

Same Skill Collection

.claude/skills/grill-me/SKILL.md
.claude/skills/prd-to-plan/SKILL.md
.claude/skills/preflight/SKILL.md
.claude/skills/tester/SKILL.md
.claude/skills/write-a-prd/SKILL.md
skills/repo-skills/add-feature-flag/SKILL.md
skills/user-skills/admin/admin-architect/SKILL.md
skills/user-skills/admin/admin-permissions/SKILL.md
skills/user-skills/admin/form-model/SKILL.md
skills/user-skills/admin/new-entry-wizard/SKILL.md
skills/user-skills/admin/website-builder/page-settings/SKILL.md
skills/user-skills/admin/website-builder/wb-preview-url-modifier/SKILL.md
skills/user-skills/api-bundle-size-limit/SKILL.md
skills/user-skills/api/api-architect/SKILL.md
skills/user-skills/api/cms-bulk-actions/SKILL.md
skills/user-skills/api/custom-field-type/SKILL.md
skills/user-skills/api/event-handler-pattern/SKILL.md
skills/user-skills/api/graphql-api/SKILL.md
skills/user-skills/api/http-route/SKILL.md
skills/user-skills/api/permissions/SKILL.md
skills/user-skills/api/use-case-pattern/SKILL.md
skills/user-skills/api/v5-to-v6-migration/SKILL.md
skills/user-skills/api/websocket-notifications/SKILL.md
skills/user-skills/cli-extensions/SKILL.md
skills/user-skills/configure-auth0/SKILL.md
skills/user-skills/configure-entraid/SKILL.md
skills/user-skills/configure-okta/SKILL.md
skills/user-skills/dependency-injection/SKILL.md
skills/user-skills/generated/api/aco/SKILL.md
skills/user-skills/generated/api/cms/SKILL.md
skills/user-skills/generated/api/file-manager/SKILL.md
skills/user-skills/generated/api/scheduler/SKILL.md
skills/user-skills/generated/api/security/SKILL.md
skills/user-skills/generated/api/system/SKILL.md
skills/user-skills/generated/api/tenancy/SKILL.md
skills/user-skills/generated/api/tenant-manager/SKILL.md
skills/user-skills/generated/api/website-builder/SKILL.md
skills/user-skills/generated/infra/SKILL.md
skills/user-skills/infrastructure-extensions/SKILL.md
skills/user-skills/local-development/SKILL.md
skills/user-skills/mailer-smtp/SKILL.md
skills/user-skills/project-structure/SKILL.md
.claude/skills/webiny-skill-creator/SKILL.md
skills/user-skills/admin/ui-extensions/SKILL.md
skills/user-skills/api/ai-powerups-content/SKILL.md
skills/user-skills/cognito-federation/SKILL.md
skills/user-skills/content-models/SKILL.md
skills/user-skills/generated/admin/aco/SKILL.md
skills/user-skills/generated/admin/ai-powerups/SKILL.md

Metadata

Files
0
Version
80eb1c5
Hash
9cef778f
Indexed
2026-08-20 10:07

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-22 03:52
浙ICP备14020137号-1 $mapa de visitantes$