Download Complete (Ebook) gRPC: Up and Running: Building Cloud Native Applications with Go and Java for Docker and Kubernetes by Kasun Indrasiri, Danesh Kuruppu ISBN 9781492058335, 1492058335, B0845YMM37 PDF for All Chapters
Download Complete (Ebook) gRPC: Up and Running: Building Cloud Native Applications with Go and Java for Docker and Kubernetes by Kasun Indrasiri, Danesh Kuruppu ISBN 9781492058335, 1492058335, B0845YMM37 PDF for All Chapters
com
DOWLOAD EBOOK
ebooknice.com
ebooknice.com
ebooknice.com
https://ebooknice.com/product/sat-ii-success-
math-1c-and-2c-2002-peterson-s-sat-ii-success-1722018
ebooknice.com
ebooknice.com
ebooknice.com
gRPC: Up and Running
Building Cloud Native Applications with Go and Java
for Docker and Kubernetes
Constant width
Used for program listings, as well as within paragraphs to refer to
program elements such as variable or function names, databases,
data types, environment variables, statements, and keywords.
TIP
This element signifies a tip or suggestion.
NOTE
This element signifies a general note.
WARNING
This element indicates a warning or caution.
NOTE
For more than 40 years, O’Reilly Media has provided technology and
business training, knowledge, and insight to help companies succeed.
Sebastopol, CA 95472
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples,
and any additional information. You can access this page at
https://oreil.ly/gRPC_Up_and_Running.
Email bookquestions@oreilly.com to comment or ask technical
questions about this book.
For more information about our books, courses, conferences, and
news, see our website at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
Acknowledgments
Our grateful thanks go to the tech reviewers of this book, Julien
Andrieux, Tim Raymond, and Ryan Michela. Also, we would like to
thank our Development Editor Melissa Potter for her guidance and
support, and our Acquisitions Editor Ryan Shaw for all the support
given. Last but not least we thank the entire gRPC community for
creating such a great open source project.
Chapter 1. Introduction to
gRPC
NOTE
Microservices Architecture
Microservices architecture is about building a software application as a
collection of independent, autonomous (developed, deployed, and
scaled independently), business capability–oriented, and loosely coupled
services.1
What Is gRPC?
gRPC (the “g” stands for something different in every gRPC release)
is an inter-process communication technology that allows you to
connect, invoke, operate, and debug distributed heterogeneous
applications as easily as making a local function call.
When you develop a gRPC application the first thing that you do is
define a service interface. The service interface definition contains
information on how your service can be consumed by consumers,
what methods you allow the consumers to call remotely, what
method parameters and message formats to use when invoking
those methods, and so on. The language that we specify in the
service definition is known as an interface definition language (IDL).
Using that service definition, you can generate the server-side code
known as a server skeleton, which simplifies the server-side logic by
providing low-level communication abstractions. Also, you can
generate the client-side code, known as a client stub, which
simplifies the client-side communication with abstractions to hide
low-level communication for different programming languages. The
methods that you specify in the service interface definition can be
remotely invoked by the client side as easily as making a local
function invocation. The underlying gRPC framework handles all the
complexities that are normally associated with enforcing strict
service contracts, data serialization, network communication,
authentication, access control, observability, and so on.
To understand the fundamental concepts of gRPC, let’s take a look at
a real-world use case of a microservice implemented with gRPC.
Suppose we are building an online retail application comprised of
multiple microservices. As illustrated in Figure 1-1, suppose that we
want to build a microservice that gives the details of the products
that are available in our online retail application (we will implement
this use case from the ground up in Chapter 2). The ProductInfo
service is modeled in such a way that it is exposed over the network
as a gRPC service.
Service Definition
gRPC uses protocol buffers as the IDL to define the service interface.
Protocol buffers are a language-agnostic, platform-neutral,
extensible mechanism to serializing structured data (we’ll cover
some of the fundamentals of protocol buffers in detail in Chapter 4,
but for now you can think of it as a data serialization mechanism).
The service interface definition is specified in a proto file—an
ordinary text file with a .proto extension. You define gRPC services in
ordinary protocol buffer format, with RPC method parameters and
return types specified as protocol buffer messages. Since the service
definition is an extension to the protocol buffer specification, a
special gRPC plug-in is used to generate code from your proto file.
In our example use case, the ProductInfo service’s interface can be
defined using protocol buffers as shown in Example 1-1. The service
definition of ProductInfo is comprised of a service interface
definition where we specify the remote methods, their input and
output parameters, and the type definition (or message formats) of
those parameters.
Example 1-1. gRPC service definition of ProductInfo service using
protocol buffers
// ProductInfo.proto
syntax = "proto3";
package ecommerce;
service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
}
message Product {
string id = 1;
string name = 2;
string description = 3;
}
message ProductID {
string value = 1;
}
gRPC Server
Once you have a service definition in place, you can use it to
generate the server- or client-side code using the protocol buffer
compiler protoc. With the gRPC plug-in for protocol buffers, you can
generate gRPC server-side and client-side code, as well as the
regular protocol buffer code for populating, serializing, and retrieving
your message types.
On the server side, the server implements that service definition and
runs a gRPC server to handle client calls. Therefore, on the server
side, to make the ProductInfo service do its job you need to do the
following:
Once you have the service implementation ready, you need to run a
gRPC server to listen for requests from clients, dispatch those
requests to the service implementation, and return the service
responses back to the client. The code snippet in Example 1-3 shows
a gRPC server implementation with Go for the ProductInfo service
use case. Here we open up a TCP port, start the gRPC server, and
register the ProductInfo service with that server.
Example 1-3. Running a gRPC server for ProductInfo service with Go
func main() {
lis, _ := net.Listen("tcp", port)
s := grpc.NewServer()
pb.RegisterProductInfoServer(s, &server{})
Visit https://ebooknice.com to
discover a wide range of
eBooks across various genres.
Enjoy exclusive deals and
discounts to enhance your
reading experience. Start your
digital reading journey today!
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
That’s all you have to do on the server side. Let’s move on to the
gRPC client-side implementation.
gRPC Client
Similar to the server side, we can generate the client-side stub using
the service definition. The client stub provides the same methods as
the server, which your client code can invoke; the client stub
translates them to remote function invocation network calls that go
to the server side. Since gRPC service definitions are language-
agnostic, you can generate clients and servers for any supported
language (via the third-party implementations) of your choice. So for
the ProductInfo service use case, we can generate the client stub
for Java while our server side is implemented with Go. In the code
snippet in Example 1-4, you find the code for Java. Despite the
programming language we use, the simple steps involved in a client-
side implementation involve setting up a connection with the remote
server, attaching the client stub with that connection, and invoking
the remote method using the client stub.
Example 1-4. gRPC client to invoke a remote method of service
// Create a channel using remote server address
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost",
8080)
.usePlaintext(true)
.build();
As you now have a good sense of the key concepts of gRPC, let’s try
to understand the gRPC client–server message flow in detail.
NOTE
Marshaling is the process of packing parameters and a remote function
into a message packet that is sent over the network, while
unmarshaling unpacks the message packet into the respective method
invocation.
Conventional RPC
RPC was a popular inter-process communication technique for
building client-service applications. With RPC a client can remotely
invoke a function of a method just like calling a local method. There
were popular RPC implementations in the early days such as the
Common Object Request Broker Architecture (CORBA) and Java
Remote Method Invocation (RMI), which were used for building and
connecting services or applications. However, most such
conventional RPC implementations are overwhelmingly complex, as
they are built on top of communication protocols such as TCP, which
hinders interoperability, and are based on bloated specifications.
SOAP
Owing to the limitations of conventional RPC implementations such
as CORBA, Simple Object Access Protocol (SOAP) was designed and
heavily promoted by large-scale enterprises such as Microsoft, IBM,
etc. SOAP is the standard communication technique in a service-
oriented architecture (SOA) to exchange XML-based structured data
between services (usually called web services in the context of SOA)
and communicates over any underlying communication protocol such
as HTTP (most commonly used).
With SOAP you can define the service interface, operations of that
service, and an associated XML message format to be used to invoke
those operations. SOAP was quite a popular technology but the
complexity of message format, as well as the complexities of
specifications built around SOAP, hinders the agility of building
distributed applications. Therefore, in the context of modern
distributed application development, SOAP web services are
considered a legacy technology. Rather than using SOAP, most of the
existing distributed applications are now being developed using the
REST architecture style.
REST
Representational State Transfer (REST) is an architectural style that
originated from Roy Fielding’s PhD dissertation. Fielding is one of the
principal authors of the HTTP specification and the originator of the
REST architectural style. REST is the foundation of the resource-
oriented architecture (ROA), where you model distributed
applications as a collection of resources and the clients that access
those resources can change the state (create, read, update, or
delete) of those resources.
The de facto implementation of REST is HTTP, and in HTTP you can
model a RESTful web application as a collection of resources
accessible using a unique identifier (URL). The state-changing
operations are applied on top of those resources in the form of the
HTTP verbs (GET, POST, PUT, DELETE, PATCH, and so on). The
resource state is represented in textual formats such as JSON, XML,
HTML, YAML, and so on.
Building applications using the REST architectural style with HTTP
and JSON has become the de facto method of building
microservices. However, with the proliferation of the number of
microservices and their network interactions RESTful services have
not been able to meet the expected modern requirements. There are
a couple of key limitations of RESTful services that hinder the ability
to use them as the messaging protocol for modern microservices-
based applications.
Inception of gRPC
Google had been using a general-purpose RPC framework called
Stubby to connect thousands of microservices that are running
across multiple data centers and built with disparate technologies.
Its core RPC layer was designed to handle an internet scale of tens
of billions of requests per second. Stubby has many great features,
but it is not standardized to be used as a generic framework as it is
too tightly coupled to Google’s internal infrastructure.
In 2015, Google released gRPC as an open source RPC framework; it
is a standardized, general-purpose, and cross-platform RPC
infrastructure. gRPC was intended to provide the same scalability,
performance, and functionality that Stubby offered, but to the
community at large.
Since then, the popularity of gRPC has grown dramatically over the
past few years with large-scale adoption from major companies such
as Netflix, Square, Lyft, Docker, Cisco, and CoreOS. Later, gRPC
joined the Cloud Native Computing Foundation (CNCF), one of the
most popular open source software foundations dedicated to making
cloud native computing universal and sustainable; gRPC gained a lot
of traction from CNCF ecosystem projects.
Now let’s look at some of the key reasons for using gRPC over the
conventional inter-process communication protocols.
Why gRPC?
gRPC is designed to be an internet-scale, inter-process
communication technology that can overcome most of the
shortcomings of conventional inter-process communication
technologies. Owing to the benefits of gRPC, most modern
applications and servers are increasingly converting their inter-
process communication protocol to gRPC. So, why would somebody
select gRPC as a communication protocol when there are so many
other options available? Let’s look more closely at some of the key
advantages that gRPC brings to the table.
Advantages of gRPC
The advantages that gRPC brings are key to the increasing adoption
of gRPC. These advantages include the following:
It’s efficient for inter-process communication
Rather than using a textual format such as JSON or XML, gRPC
uses a protocol buffer–based binary protocol to communicate
with gRPC services and clients. Also, gRPC implements protocol
buffers on top of HTTP/2, which makes it even faster for inter-
process communication. This makes gRPC one of the most
efficient inter-process communication technologies out there.
It’s polyglot
gRPC is designed to work with multiple programming languages.
A gRPC service definition with protocol buffers is language-
agnostic. Hence, you can pick the language of your choice but
can interoperate with any existing gRPC service or client.
It has duplex streaming
gRPC has native support for client- or server-side streaming,
which is baked into the service definition itself. This makes it
much easier to develop streaming services or streaming clients.
And the ability to build conventional request–response style
messaging and client- and server-side streaming is a key
advantage over the conventional RESTful messaging style.
It has built-in commodity features
gRPC offers built-in support for commodity features such as
authentication, encryption, resiliency (deadlines and timeouts),
metadata exchange, compression, load balancing, service
discovery, and so on (we’ll explore these in Chapter 5).
Disadvantages of gRPC
Here are some of the disadvantages of gRPC that you need to be
mindful of when you select it for building applications. These include
the following:
It may not be suitable for external-facing services
Exploring the Variety of Random
Documents with Different Content
into his blood. At the same instant he was conscious of a stab of
shame. It was the flesh, the draperies, the trappings to which his
pulses responded; it was not the magical secret which was contained
in the miniatures upon the walls, in the passionate delicacy of the
cadences which sobbed themselves out liquidly under the siren’s
touch of this beautiful woman.
He stood in front of the cosy fire, glass in hand. A soft warmth
overspread his being. His eyes glanced from the white shoulders of
the enchantress to the thousand and one hues which were blended
so cunningly in the carpets and tapestries. The subtle playings of
light and shadow, the mellow effects of the atmosphere, the
softness of the music, began to assail his senses with indescribable
pangs. He feasted his eyes, his ears, his nostrils; they rewarded him
with gladness. His heart beat violently.
“These rare kinds of genius, are they not barbarous?” he said, when
the siren had ceased to cast her fingers.
“It is like children lisping,” she said, half-turning her head, with a
smile that curved her mouth entrancingly.
“Yes,” said the young man, “poetry, romance, imagination are
primitive; they belong to the childhood of nations, to the dawn of
new worlds. What a divine inspiration these sweet-voiced children of
nature who are bought out of due time, these unhappy Poles,
Germans, and Frenchmen bring to their despair. Instead of sitting
down in black coats to make their music into beef and mutton, they
should be tripping through the glades piping to the birds, the trees,
the bright air.”
“This is a mad fellow, my angel,” said Mr. Whitcomb indulgently, “but
if you are gentle with him you may find him amusing.”
“Mr. Northcote will amuse me enormously,” said the lady, with a
demure glance.
“Is it thus you rebuke his madness?” the young man asked.
“On the contrary, I don’t think I have ever seen a sanity that is quite
so perfect.”
“Drop it,” said the solicitor, roguishly pinching her ear. “Beware of
dangerous turnings, my son. She is quite prepared to play George
Sand to anybody’s Alfred de Musset. She even does it to the
greengrocer when he comes round with his barrow. I understand
they discourse divinely together upon the subject of cabbages.”
“But Witty is too much the man of the world to be jealous about it,”
she purred.
“If Pussy hasn’t the opportunity to sharpen her claws on a sofa or an
ottoman, she doesn’t mind a wicker-work chair.”
“Witty, darling,” said the lady, “I hate to find rudeness keeping
company with real distinction of mind.”
“Upon my word,” expostulated Northcote, seeking to measure her
depth, “I consider that rebuke to be much prettier than the one
bestowed upon me.”
“When, Mr. Northcote, did I rebuke you?”
“Did you not say I should amuse you enormously?”
“Is not that the only compliment a woman has the power to pay
nowadays?”
“Yes, Noodle,” said Mr. Whitcomb, laughing; “but don’t you see how
young he is, and therefore how serious? Who would call ‘enormously
amusing’ a fitting compliment for one of the seven champions of
Christendom? This is a devil of a fellow.”
“I can roar you like any sucking dove,” said the young man.
“How it would thrill one to hear you do it!” said the lady, enfolding
him with large eyes.
“He is a man of destiny,” said Mr. Whitcomb; “he carries a genie in
his pocket.”
“Oh!” said the lady, with clasped hands.
“One of these fine mornings he will stand the world on its head.”
“O-o-o-o-h!” said the lady.
“And having done that,” said Northcote, “this amazing fellow will dig
a hole in the universe for to bury the moon.”
“I would that all men had ambition,” said the lady, looking down at
her shoe. “If Witty had only a little of that precious salt which forms
a sediment at the bottom of every fine action he would be one’s
beau-ideal of a hero, a Christian, and a philosopher.”
“Minx!” exclaimed the solicitor. “If it were not for my ambition I
should never rise from my bed.”
“So this wonderful Mr. Whitcomb has no ambition!” said Northcote.
“You see I have found his character so complex, that in my capacity
of an amateur of the human mind I am picking it out, here a little,
there a little, piece by piece.”
“You must give him no marks for ambition,” said the lady. “But since
when did you become acquainted with him not to have found out
that?”
“Since this evening at ten.”
“Ah, then, you are absolved. He will certainly baffle you at first.”
“He is wholly incomprehensible to me. He is a man of moods who
oughtn’t to have any.”
The lady clapped her hands in a little ripple of glee.
“How right,” she cried. “In a dozen little words you have shown me
the nothingness of my own knowledge.”
“Of course he has, Vapid One,” said Mr. Whitcomb. “Have I not told
you he carries a genie in his pocket?”
“Then that is why his eyes are so deep and bright,” said the lady,
turning to peruse Northcote again with an unfathomable coquetry;
“and would you not say, Witty, that the genie is in some sort
responsible for his mouth?”
“Is this public laying of one another upon the dissecting-table a new
parlor-game that has been brought into vogue by the long winter
evenings, may I ask?” said Mr. Whitcomb, concealing a yawn.
“Pray do not be insolent, Witty. The proper study of mankind is
Man.”
“In the words of Pope,” said the solicitor, turning to replenish his
glass.
“You can see how Mr. Whitcomb baffles me,” said Northcote, who did
not propose to lose the opportunity of following up his clue.
“Is it his attitude to hansom cabmen that makes him so dark?”
“That is contributory. But it is mainly because he has come before
me in the guise of a waverer that I stand so much at fault. If one
knows anything about anything one would be prepared to affirm that
nature had designed Samuel Whitcomb to know his own mind.”
“He does as a rule. I have never known him waver in anything; but
then, of course, it is only quite recently that he has begun to
associate with dangerous persons who keep a genie.”
“Do you suggest that he is susceptible to such a thing as a genie?
Would it have a malign influence upon him, do you suppose?”
“I would suggest it to be likely in the highest degree.”
“Now, look here, my young friends,” interposed the solicitor at this
point, with a broad good humor, “Samuel Whitcomb does not
propose to play the part of the corpse at the lecture on anatomy.”
“You will help yourself to another drink like a good boy,” said the
lady severely; “and you will please to say nothing until we have dealt
with your ‘case.’ Your character need not fear the lancet and bistoury
of true science. Tell me, Mr. Northcote, wherein he is a waverer.”
“I am rejoiced to hear you put that question,” said the young man,
with a gesture of triumph he did not try to conceal, “for now it is
that I unfold my tale.”
XII
THE FAITH OF A SIREN
“At about ten o’clock this evening,” Northcote began, “as I was
kneeling in front of the fire—there was not any fire, by the way, as it
costs too much to afford one sometimes—in my miserable dwelling
at the top of Shepherd’s Inn, the oldest and most moribund of all the
buildings in Fleet Street, who should come climbing up to the
topmost story of the rickety and unwholesome stairs, under which
the rats have made their home for many generations, but Mr.
Whitcomb. And what do you suppose was his business?”
“He wished to buy one of your pictures.”
“Ah, no, I am not a painter.”
“I thought there was a chance of it, since they say all very good
painters are so poor. But perhaps you are a little too fierce, although
I am told these impressionists are terrible men.”
“The painting of pictures is one of the few things I have not
attempted,” said the young man, consenting to this interruption that
he might sit for his own portrait.
“Well, I should not say you are a writer of fiction. They are so tame.
Besides they are all nearly as rich as solicitors.”
“Why not a poet?”
“Why not? although your fierceness would make you a dramatic, not
a lyric one. Still it is impossible for you to be a poet, because I am
sure that Witty would never have climbed up all those stairs to your
miserable garret—I feel sure it is a garret with a sloping roof with a
hole in it—”
“There is a pool under the hole which has been caused by the
percolation of water—”
“On to the atrocious bare boards, its occupant being much too poor
to afford a carpet. Yes, Witty would never have climbed up to your
garret if you had been a poet. Or stay, he might, had you been Mrs.
Felicia Hemans. As you are a seeker of documentary evidence, he
has been known to recite her poems, at the request of the rector of
this parish, to a Sunday-school party.”
“Base woman,” said the solicitor, with an air of injury; “I claim to be
an admirer of the poet Longfellow.”
“Never, Witty, in your heart; it is merely your fatal craving to be
respectable in all things. But in the matter of poetry you must be
content to remain outside. You would never have climbed those
rickety stairs to that cold garret to see John Keats.”
“Well, now, Featherhead, did I not tell you at the first that our young
friend was England’s future Lord Chancellor?”
“I will never believe that; I will never believe that his destiny is the
law. His eye has amazing flashes; and is there not a beautiful
eloquence burning in his mouth? I cannot think of him as rich Witty,
and successful Witty, and smug Witty, like you atrocious lawyers. He
is one who would be an overthrower of dynasties, a saviour of
societies.”
“You are letting your tongue wag, Noodle. If you talk so much it will
take the young man until daybreak to unfold his story.”
“I am an advocate,” said Northcote.
“An advocate,” said the lady softly; “yes, I think you may be that.
One no more associates an advocate with the law than one
associates a poet with a publisher.”
“You would say,” said Northcote, “that it is the function of an
advocate to draw his sword for the truth, for progress, for justice,
for every human amenity?”
“I would, indeed. Why, if one thinks about it, surely it is nobler to be
an advocate than to be a poet or a soldier. One might say it was the
highest calling in the world.”
“Then let us say it,” said the young man, “for I verily believe it to be
so.”
“And what, pray, was Witty’s business with this advocate?”
“They are going to hang a woman; and Mr. Whitcomb, who to his
infinite complexities and many-sidedness as a citizen of the world
adds a leaven of the finest humanitarian principles, has undertaken
to save the poor creature from a fate so pitiful.”
“To hang a woman!” said the lady, drawing in her breath with a
sharp sound. “Is it still possible to hang a woman at this time of
day?”
“Perfectly,” said the young man. “They do it in every Christian
country.”
“Then the world has need for an advocate,” said the lady, with
horror in her eyes. “It is necessary that we should have yet another
champion for our sex in Christendom. Yes, this was he whom Witty
came to seek in that garret at the top of all those rickety stairs.”
“He came to seek, and found no less a person,” said Northcote. “And
having found this authentic champion of your sex, he gave him a
mandate to plead on behalf of this unfortunate creature, the least
happy of all its members.”
“What a moment of high inspiration for us and for him,” said the
lady, with a glance of tenderness.
“It was even as you say. But I would have you mark what follows.
Scarcely has he bestowed these high plenary powers upon one
whom he has ventured to select from among all the great multitude
to champion your sex in the name of humanity, than for a whim he
withdraws his mandate.”
“Impossible; it would be an outrage upon us.”
“Yes; unconditionally and peremptorily he withdraws his mandate.”
“Impossible; they will do the poor creature to death.”
“Yes, they will do her to death. He who has been called to the office
of averting her doom has decreed that she must walk to embrace it
without a friend to plead her cause before humanity.”
“Surely this cannot be; society itself must protest.”
“One expects it; yet things are as they are.”
The beautiful creature turned to the solicitor with an almost royal air.
“What, sir, can you find to say in your defence?”
Mr. Whitcomb gave a short laugh.
“I yield,” said he.
“You restore the mandate?”
“Yes, yes, yes! My blood be on my own head, but so it must be. It is
beyond flesh and blood to withstand such a pair. You, madam, are a
sorceress; and this fellow is the devil.”
“I am content to be a sorceress in the cause of my unfortunate sex,”
cried the lady; and turning to Northcote added gravely: “And is it not
high time that we acquired a devil for our advocate?”
Northcote, who from the moment of her first appearance had
foreseen a victory, took her hand to his lips impulsively, with an
expression of gratitude.
“I hope this will be all right,” said the solicitor, viewing his surrender
with a rueful smile. “You see it is the first time in my life that a
foreboding has overtaken me in the midst of action. Whether it is
the importance of the case, the obscurity of the advocate, or a
certain flamboyancy in his bearing which is so repugnant to an
English common lawyer, I cannot tell; but let me confess that I have
already a premonition that I have been guilty of a mistake. And I will
go farther,” said Mr. Whitcomb, with a wry laugh; “I even see ruin,
blue ruin for all concerned, hidden in this irresolute act. Sharp little
shivers go down my spine.”
“It is no more than the reaction,” said Northcote, “which attends our
highest resolves. Is it not in such moments that a man truly
measures himself? It must have been at the fall of the barometer
that Samson was shorn of his locks.”
“Is there not always a woman in these cases?” said the lady. “This
unfortunate creature whom our advocate is to deliver from the
gallows, may she not be a Delilah of some kind?”
XIII
BE BOLD, WARY, FEAR NOT
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebooknice.com