Add some basic docs

This commit is contained in:
Dave Syer
2024-10-25 11:01:54 +01:00
parent b5a623231a
commit 6be591d544
6 changed files with 194 additions and 9 deletions

View File

@@ -1,5 +1,6 @@
* xref:index.adoc[Overview]
* xref:concepts.adoc[GRPC Concepts]
* xref:getting-started.adoc[Getting Started]
* xref:server.adoc[GRPC Server]
* xref:client.adoc[GRPC Clients]
* xref:contribution-guidelines.adoc[Contribution Guidelines]
* xref:appendix.adoc[]

View File

@@ -0,0 +1,101 @@
[[client]]
= GRPC Client
This section describes core concepts that Spring gRPC uses on the client side.
== Create a `Channel`
You can inject a `GrpcChannelFactory` into your application configuration and use it to create a gRPC channel.
The most common usage of a channel is to create a client that binds to a service.
The Protobuf-generated sources in your project will contain the stub classes, and they just need to be bound to a channel.
The Protobuf files will be provided by the service you are connecting to.
For example, consider the `SimpleGrpc` service generated by the Protobuf tooling in your build.
To bind to this service on a local server:
[source,java]
----
@Bean
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:9090").build());
}
----
The `GrpcChannelFactory` creates a `ChannelBuilder` that you can customize before building the channel if necessary.
=== Shaded Netty Client
The default client implementation uses the Netty client.
You can switch to a shaded Netty implementation provided by the gRPC team by adding the `grpc-netty-shaded` dependency and excluding the `grpc-netty` dependency.
[source,xml]
----
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
</dependency>
----
For Gradle users
[source,gradle]
----
dependencies {
implementation "org.springframework.grpc:spring-grpc-spring-boot-starter"
modules {
module("io.grpc:grpc-netty") {
replacedBy("io.grpc:grpc-netty-shaded", "Use Netty shaded instead of regular Netty")
}
}
}
----
== Channel Configuration
The default `GrpcChannelFactory` implementation can also create a "named" channel, which you can then use to extract the configuration to connect to the server.
For example:
[source,java]
----
@Bean
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return SimpleGrpc.newBlockingStub(channels.createChannel("local").build());
}
----
then in `application.properties`:
[source,properties]
----
spring.grpc.client.channels.local.address=0.0.0.0:9090
----
There is a default named channel (named "default") that you can configure in the same way, and then it will be used by default if there is no channel with the name specified in the channel creation.
Beans of type `GrpcChannelConfigurer` can be used to customize the `ChannelBuilder` before the channel is built.
This can be useful for setting up security, for example.
== The Local Server Port
If you are running a gRPC server locally as part of your application, you will often want to connect to it in an integration test.
It can be convenient in that case to use an ephemeral port for the server (`spring.grpc.server.port=0`) and then use the port that is allocated to connect to it.
You can discover the port that the server is running on by injecting the `@LocalGrpcPort` bean into your test.
The `@Bean` has to be marked as `@Lazy` to ensure that the port is available when the bean is created (it is only known when the server starts which is part of the startup process).
[source,java]
----
@Bean
@Lazy
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels, @LocalGrpcPort int port) {
return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:" + port).build());
}
----

View File

@@ -1,4 +0,0 @@
[[concepts]]
= GRPC Concepts
This section describes core concepts that Spring gRPC uses. We recommend reading it closely to understand the ideas behind how Spring gRPC is implemented.

View File

@@ -84,8 +84,6 @@ As shown in the snippet below this can then be followed by version-less declarat
----
dependencies {
implementation platform("org.springframework.ai:spring-grpc-dependencies:1.0.0-SNAPSHOT")
// Replace the following with the starter dependencies of specific modules you wish to use
implementation 'org.springframework.ai:spring-grpc-openai'
}
----

View File

@@ -3,7 +3,9 @@
The `Spring gRPC` project aims to streamline the development of gRPC applications.
The xref:concepts.adoc[concepts section] provides a high-level overview of gRPC concepts and their representation in Spring gRPC.
The xref:getting-started.adoc[Getting Started] section shows you how to create your first gRPC application.
Subsequent sections delve into each component and common use cases with a code-focused approach.
The xref:server.adoc[server section] provides a high-level overview of gRPC servers and their representation in Spring gRPC.
The xref:server.adoc[client section] does the same for gRPC clients. A gRPC application can be a client and a server at the same time.

View File

@@ -0,0 +1,87 @@
[[server]]
= GRPC Server
This section describes core concepts that Spring gRPC uses on the server side. We recommend reading it closely to understand the ideas behind how Spring gRPC is implemented.
You only need to provide one or more beans of type `BindableService` to create a gRPC server, provided the classpath contains an implementation of a `Server`. The `BindableService` is a gRPC service that can be bound to a server.
The `Server` is the gRPC server that listens for incoming requests and routes them to the appropriate service implementation.
== Create a `BindableService`
To create a gRPC server, you need to provide one or more beans of type `BindableService`.
There are some `BindableServices` available off the shelf that you could include in your application (an example is the reflection service from the `grpc-services` artifact which allows clients to browse the metadata of your services and download the Portobuf files).
Very commonly, you will create your own `BindableService` by extending the generated service implementation from your Protobuf file.
The easiest way to do it is to simply add a Spring `@Service` annotation to the implementation class and have it picked up by the `@ComponentScan` in your Spring Boot application.
== Netty Server
If you use the `spring-grpc-spring-boot-starter` dependency on its own, the `Server` is a Netty-based implementation.
You can configure common features of the server by using the `grpc.server` prefix in `application.properties` or `application.yml`.
For instance, to set the port to listen on, use `spring.grpc.server.port` (defaults to 9090).
For more specialized configuration, you can provide a `ServerBuilderCustomizer` bean to customize the `ServerBuilder` before it is used to create the server.
=== Shaded Netty
You can switch to a shaded Netty provided by the gRPC team by adding the `grpc-netty-shaded` dependency and excluding the `grpc-netty` dependency.
[source,xml]
----
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
</dependency>
----
For Gradle users
[source,gradle]
----
dependencies {
implementation "org.springframework.grpc:spring-grpc-spring-boot-starter"
modules {
module("io.grpc:grpc-netty") {
replacedBy("io.grpc:grpc-netty-shaded", "Use Netty shaded instead of regular Netty")
}
}
}
----
== Servlet Server
Any servlet container can be used to run a gRPC server.
Spring gRPC includes autoconfiguration that configures the server to use the servlet container if it detects that it is in a web application, so all you have to do is include `spring-boot-starter-web` in your application.
[source,xml]
----
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-spring-boot-starter</artifactId>
</dependency>
----
For Gradle users
[source,gradle]
----
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.grpc:spring-grpc-spring-boot-starter"
}
----
The `spring.grpc.server.*` properties will be ignored in facour of the regular `server.*` properties in this case.
The servlet that is created is mapped to process HTTP POST requests to the paths defined by the registered services, as `/<service-name>/*`.
Clients can connect to the server using that path, which is what any gRPC client library will do.