Merge pull request #389 from 0808zhongshang/dubbo3

docs
diff --git a/docs/guide/dubboForWEB/Errors.md b/docs/guide/dubboForWEB/Errors.md
index 165d08c..f401269 100644
--- a/docs/guide/dubboForWEB/Errors.md
+++ b/docs/guide/dubboForWEB/Errors.md
@@ -1 +1,97 @@
 # Errors
+
+Similar to the familiar "404 Not Found" and "500 Internal Server Error" status codes you may have seen in HTTP, Dubbo uses a set of 16 error codes. In the Dubbo protocol, an error is always represented as JSON, and is easily readable in the developer tools of your browser. For example:
+
+```
+HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+{
+  "status": "3"
+  "message": "sentence cannot be empty"
+}
+```
+
+With the gRPC-web protocol, errors are usually not human-readable, but Dubbo provides a common type that represents errors consistently across all supported protocols.
+
+# Working with errors
+
+All errors are represented by [`DubboError`](https://github.com/apache/dubbo-js/blob/dubbo3/packages/dubbo/src/code.ts), a subtype of the built-in `Error` class. Using a try-catch block, we can catch any error that occurred during a call:
+
+```tsx
+import { DubboError } from "@apachedubbo/dubbo";
+
+try {
+  await client.say({sentence: ""});
+} catch (err) {
+  // We have to verify err is a DubboError
+  // before using it as one.
+  if (err instanceof DubboError) {
+    err.code;    // Code.InvalidArgument
+    err.message; // "[invalid_argument] sentence cannot be empty"
+  }
+  // Alternatively, we can use DubboError.from()
+  // It returns a DubboError as is, and converts any
+  // other error to a DubboError.
+  const DubboError = DubboError.from(err);
+  DubboErr.code;    // Code.InvalidArgument
+  DubboErr.message; // "[invalid_argument] sentence cannot be empty"
+}
+```
+
+# Error codes
+
+The `code` property holds one of Connect's error codes. All error codes are available through the TypeScript enumeration [`Code`](https://github.com/apache/dubbo-js/blob/dubbo3/packages/dubbo/src/code.ts). Note that a code is an integer value, but can easily be converted to and from a string value.
+
+```tsx
+import { Code } from "@apachedubbo/dubbo";
+
+let code = Code.InvalidArgument;
+code; // 3
+let name = Code[code]; // "InvalidArgument"
+let val: Code = Code["InvalidArgument"]; // 3
+```
+
+# Error messages
+
+The `message` property contains a descriptive error message. In most cases, the message is provided by the backend implementing the service. Because `message` is the only property that shows up in the browser console for uncaught errors, the error message is always prefixed with the error code. In case you *do* want the original error message without a code prefix, use the property `rawMessage`.
+
+```tsx
+err.message; // "[invalid_argument] sentence cannot be empty"
+if (err.code == Code.InvalidArgument) {
+  err.rawMessage; // "sentence cannot be empty"
+}
+```
+
+# Metadata
+
+If you catch an error, your program takes an exception from the regular code path, but you might still want to access a header or trailer value. Connect provides a union of header and trailer values in the `metadata` property as a simple `Headers` object:
+
+```tsx
+err.metadata.get("Custom-Header-Value");
+err.metadata.get("Custom-Trailer-Value");
+```
+
+# Error details
+
+On the wire, error details are wrapped with `google.protobuf.Any`, so that a server or middleware can attach arbitrary data to an error. Using the method `findDetails()`, you can decode the details from an error.
+
+The method takes a protobuf message type as an argument, and returns an array of decoded messages of this type.
+
+This example looks up a localized error message in the users preferred language:
+
+```tsx
+import { DubboError } from "@apachedubbo/dubbo";
+import { LocalizedMessage } from "./error_details_pb.js";
+
+function handle(err: DubboError) {
+  const localized = err.findDetails(LocalizedMessage)
+    .find(i => i.locale === navigator.language);
+  console.log(localized?.message);
+}
+```
+
+We are using the protobuf message [`google.rpc.LocalizedMessage`](https://buf.build/googleapis/googleapis/file/main:google/rpc/error_details.proto#L241) in this example, but any protobuf message can be transmitted as error details.
+
+Alternatively, `findDetails()` takes a registry as an argument. See the [protobuf-es documentation](https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#registries) for details.
+
diff --git a/docs/guide/dubboForWEB/GetRequestsandCaching.md b/docs/guide/dubboForWEB/GetRequestsandCaching.md
index cbc8498..06de22d 100644
--- a/docs/guide/dubboForWEB/GetRequestsandCaching.md
+++ b/docs/guide/dubboForWEB/GetRequestsandCaching.md
@@ -1 +1,19 @@
-# GetRequestsandCaching
+# Get Requests and Caching
+
+Dubbo supports performing idempotent, side-effect free requests using an HTTP GET-based protocol. This makes it easier to cache certain kinds of requests in the browser, on your CDN, or in proxies and other middleboxes.
+
+First, configure your server to handle HTTP GET requests using Dubbo. 
+
+Afterwards, ensure that a new enough version of `@apachedubbo/dubbo-web` is set up; HTTP GET support is available inDubbo Web v3.3.0 or newer. Then, you can specify the `useHttpGet` option when creating the Dubbo transport:
+
+```tsx
+const transport = createDubboTransport({
+  baseUrl: "http://localhost:8080",
+  httpVersion: "1.1",
+});
+const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' });
+const res = client.say({ sentence: "Hello World" });
+console.log(res);
+```
+
+Methods annotated as side-effect free will use GET requests. All other requests will continue to use POST.
\ No newline at end of file
diff --git a/docs/guide/dubboForWEB/ServerSideRendering.md b/docs/guide/dubboForWEB/ServerSideRendering.md
index 33329f7..883bad4 100644
--- a/docs/guide/dubboForWEB/ServerSideRendering.md
+++ b/docs/guide/dubboForWEB/ServerSideRendering.md
@@ -1 +1,96 @@
-# Server-SideRendering
+# Server-Side Rendering (SSR)
+
+Many frameworks offer server-side rendering (SSR) support, which is the ability to render a page on the server-side and then send this information to the client as HTML. SSR provides many benefits such as:
+
+- Better Search Engine Optimization (SEO) support.
+- Resilience in the face of issues such as network connectivity, ad blockers, and obstacles to loading JavaScript.
+- The ability to incrementally render data without forcing the user to wait for the entire page to load.
+
+The last benefit is where Dubbo-ES fits in. Consider a scenario where your application needs to make many API requests for data that rarely changes. Using Dubbo-ES with SSR allows you to perform these fetches on the server, significantly reducing the time to [First Contentful Paint](https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint), which is a metric that measures the time from when the page starts loading to when any part of the page's content is rendered on the screen
+
+Unfortunately, the ecosystem supporting SSR is still in its infancy. Each framework offers wildly different approaches to implementing it, so there is a lot of nuance involved.
+
+The main thing to be aware of when dealing with SSR is that any data that crosses a network boundary (i.e. from server to client) must be able to be serialized to JSON. With most regular JavaScript primitives, this is not an issue, but if you want to return your entire response message or more complex data structures, you will need to convert them into a form that is JSON-serializable. This can be done one of two ways:
+
+### toPlainMessage
+
+The `toPlainMessage` is a function exposed by the [`@bufbuild/protobuf`](https://www.npmjs.com/package/@bufbuild/protobuf) package. This function will convert a Dubbo-ES response into its [`PlainMessage`](https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#plainmessage) equivalent, which is an object containing just the fields of a message and none of the message's methods. Additionally, you can safely convert a `PlainMessage` to a full message again with the message constructor.
+
+NOTE
+
+This approach will leave any `BigInt` or `Uint8Array` types in your messages as-is.
+
+### toJson
+
+In addition to `toPlainMessage`, you can also convert your message to JSON explicitly using the [`toJson`](https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#json) method that every message provides. The downside to this approach is that you lose all type information when converted to JSON, but you can get it back in your client by simply converting into the original message type using `fromJson`.
+
+NOTE
+
+This approach will work for any messages which contain a `BigInt` or `Uint8Array` type, because the `toJson` method will convert them to their correct JSON representation.
+
+## Examples
+
+Let's walk through a few examples in various setups and discuss some gotchas when using Dubbo-ES as part of your data fetching strategy with SSR.
+
+### Svelte
+
+Svelte allows you to customize your data fetching strategy by defining `load` functions which do the actual fetching. All `load` functions provide a custom [`fetch`](https://kit.svelte.dev/docs/load#making-fetch-requests) function, which behaves identical to the native Fetch API with a few added benefits. There are two types of `load` functions you can define: **server** and **universal**.
+
+#### Server load functions
+
+Server load functions always run on the server and the data they return is then made available to your page via props. Because of this, any data you fetch with Dubbo-ES and return from your server load function must be serializable to JSON since it is crossing the aforementioned network boundary. This is where the usage of `toPlainMessage` or `toJson`come into play.
+
+An example of using both in a Svelte server load function:
+
+```ts
+import { toPlainMessage } from "@bufbuild/protobuf";
+import { createPromiseClient } from "@apachedubbo/dubbo";
+import { createConnectTransport } from "@apachedubbo/dubbo-web";
+import { ElizaService } from "./gen/eliza_dubbo.js";
+
+export const load = async ({ fetch, params }) => {
+    const transport = createDUbboTransport({
+        // All transports accept a custom fetch implementation.
+        fetch,
+        // With Svelte's custom fetch function, we could alternatively
+        // use a relative base URL here.
+        baseUrl: "http://localhost:8080",
+    });
+    const client = createPromiseClient(ElizaService, transport);
+    const request = { sentence: "Hello from the server" };
+    const response = await client.say(request);
+
+    // This returned object will be available to your page via props.
+    return {
+        // Use toPlainMessage to make the response serializable
+        response: toPlainMessage(response),
+        // Or use toJson to convert it to JSON explicitly
+        // Just remember to convert it back using fromJson if you want your original message types
+        responseAsJson: response.toJson(),
+    };
+};
+```
+
+#### Universal load functions
+
+Universal load functions run on the server on page load. The fetched data is then serialized and embedded into the page. Universal load functions are then invoked again during hydration of the page and all subsequent invocations are done on the client. Because of this, you do not need to make your messages JSON-serializable using the above methods.
+
+However, with universal load functions, you will be constrained to using the Dubbo transport only. With gRPC-Web or any other binary data (this includes the Protobuf binary format and all streaming RPCs), Svelte falls back to always run the function in the browser. For details, see [this issue](https://github.com/sveltejs/kit/issues/8302).
+
+### Next.js
+
+The Next.js framework provides SSR support in a variety of ways. Similar to Svelte, you can architect your SSR data-fetching strategy by defining one of two functions depending on your use case. The function `getStaticProps` is invoked at build time when running `next build` and can be used to fetch data that is available and applicable to retrieve during your build process. This data is then used to render the page and the fully-built HTML is available at runtime.
+
+The function `getServerSideProps` is invoked at request time and is used to fetch data when a page is requested. The returned data is then passed to your component in props. Because of this, though, we have the same issue as above with crossing the serialization boundary. All data returned from this function will need to be converted to something JSON-serializable. This can be accomplished through the use of  `toPlainMessage` or `toJson`discussed above.
+
+Note that `getStaticProps` and `getServerSideProps` are features of the Next.js Pages Router. Version 13 of Next.js adds the new App Router, which uses React Server Components instead.
+
+For a working example of `getServerSideProps` with Next.js, check out the [Next.js](https://github.com/connectrpc/examples-es/tree/main/nextjs) project in our [examples-es](https://github.com/connectrpc/examples-es) repo.
+
+# React Server Components
+
+React Server Components (RSC) are an additional mechanism for server-side rendering. While a few frameworks offer support for them, only Next.js is mentioned on React's own page for [Bleeding-Edge Frameworks](https://react.dev/learn/start-a-new-react-project#bleeding-edge-react-frameworks), so we will discuss them here in the context of a Next.js application.
+
+By default in Next.js, all components are considered React Server Components. Rendering is done on the server and to render on the client, you must explicitly opt-in to do so. Note though that when using React Server Components in Next.js, you aren't necessarily subject to the same restrictions regarding JSON serialization. You can fetch data and render it server-side without needing to serialize it since it is not crossing a boundary using just RSC.
+
+However, keep in mind that you *do* cross the network boundary if you interleave server and client components. In this case, the same restrictions apply as mentioned above. You cannot pass full `Message` instances, but you can use `toPlainMessage` to convert them to their `PlainMessage` counterparts. React Server Components in Next.js handle `BigInt` properly, but be careful with `Uint8Array`, as they are converted to regular arrays. You can restore them by wrapping them with a call to the `Uint8Array` constructor.
\ No newline at end of file