Implementing CREATE operation
Table of contents
- What you need
- 1. Implement server-side
- 2. Create a client
- 3. Implement client-side
- 4. Create a test file
- 5. Register a ServerExtension
- 6. Test creating a blog post
- What's next
In the previous step, we defined empty service methods.
In this step, we'll fill in one of the service methods to create a blog post and implement a corresponding client method.
Also, we'll try making a call to the service method with test code using Armeria's ServerExtension
.
What you need
You need to have the following files obtained from previous steps. You can always download the full version, instead of creating one yourself.
- Generated Java code
Main.java
BlogServiceImpl.java
1. Implement server-side
Let's implement a service method to create a blog post.
In the
BlogServiceImpl
class, create an ID generator to issue temporary blog post IDs and a map to contain blog posts.BlogServiceImpl.javaimport java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; public class BlogServiceImpl implements BlogService.AsyncIface { private final AtomicInteger idGenerator = new AtomicInteger(); private final Map<Integer, BlogPost> blogPosts = new ConcurrentHashMap<>(); ... }
In the
createBlogPost()
method, create aBlogPost
object with a generated ID and request parameters.BlogServiceImpl.javaimport java.time.Instant; ... @Override public void createBlogPost(CreateBlogPostRequest request, AsyncMethodCallback<BlogPost> resultHandler) throws TException { final int id = idGenerator.getAndIncrement(); final Instant now = Instant.now(); final BlogPost blogPost = new BlogPost() .setId(id) .setTitle(request.getTitle()) .setContent(request.getContent()) .setModifiedAt(now.toEpochMilli()) .setCreatedAt(now.toEpochMilli()); }
In the
createBlogPost()
method, save the post information in theblogPosts
map and return the information of the created blog post to theresultHandler
.BlogServiceImpl.java@Override public void createBlogPost(CreateBlogPostRequest request, AsyncMethodCallback<BlogPost> resultHandler) throws TException { ... blogPosts.put(id, blogPost); final BlogPost stored = blogPost; resultHandler.onComplete(stored); }
2. Create a client
Let's create a client to send a request to the service. You can refer to the full version of the file here of the file.
Create a class for our client. We'll name the class
BlogClient
.BlogClient.javapackage example.armeria.server.blog.thrift; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BlogClient { private static final Logger logger = LoggerFactory.getLogger(BlogClient.class); }
In the
BlogClient
class, add a constructor and create a Thrift client instance using Armeria'sThriftClients
.BlogClient.javaimport java.net.URI; import com.linecorp.armeria.client.thrift.ThriftClients; import example.armeria.blog.thrift.BlogService; public class BlogClient { ... private final BlogService.Iface blogService; BlogClient(URI uri, String path) { blogService = ThriftClients.builder(uri) .path(path) .build(BlogService.Iface.class); } }
3. Implement client-side
In the BlogClient
class, add a method to send a request to create a blog post.
import org.apache.thrift.TException;
import example.armeria.blog.thrift.BlogPost;
import example.armeria.blog.thrift.CreateBlogPostRequest;
...
BlogPost createBlogPost(String title, String content) throws TException {
final CreateBlogPostRequest request =
new CreateBlogPostRequest().setTitle(title)
.setContent(content);
return blogService.createBlogPost(request);
}
4. Create a test file
Let's start writing test code. We'll use test code to verify what we implement along the way.
Create a file, BlogServiceTest.java
, under {project_root}/src/test/java/example/armeria/server/blog/thrift
as follows.
You can see the full version of the file here.
package example.armeria.server.blog.thrift;
class BlogServiceTest {}
5. Register a ServerExtension
Armeria's ServerExtension
automatically handles set-up and tear-down of a server for testing.
This is convenient as it eliminates the need to execute the main method to set up a server before running our tests.
In the BlogServiceTest
class, register a ServerExtension
as follows.
Note that the service instance is added to the configuration.
import org.junit.jupiter.api.extension.RegisterExtension;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.thrift.THttpService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
...
@RegisterExtension
static final ServerExtension server = new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service("/thrift",
THttpService.builder()
// Add the service to the configuration
.addService(new BlogServiceImpl())
.build());
}
};
6. Test creating a blog post
Let's test if we can create a blog post.
In the
BlogServiceTest
class, add a test method as follows.BlogServiceTest.javaimport static org.assertj.core.api.Assertions.assertThat; import org.apache.thrift.TException; import org.junit.jupiter.api.Test; import example.armeria.blog.thrift.BlogPost; ... @Test void createBlogPost() throws TException { final BlogClient client = new BlogClient(server.httpUri(), "/thrift"); final BlogPost response = client.createBlogPost("My first blog", "Hello Armeria!"); assertThat(response.getId()).isGreaterThanOrEqualTo(0); assertThat(response.getTitle()).isEqualTo("My first blog"); assertThat(response.getContent()).isEqualTo("Hello Armeria!"); }
Run the test case on your IDE or using Gradle.
./gradlew test
The service worked as expected if you see the test case passed.
What's next
In this step, we've implemented a method for creating a blog post.
We've also written test code and registered ServerExtension
to our test.
Next, at Step 4. Implement READ, we'll implement a READ operation to read a single post and also multiple posts.