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.javaBlogServiceImpl.java
1. Implement server-side
Let's implement a service method to create a blog post.
In the
BlogServiceImplclass, 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 aBlogPostobject 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 theblogPostsmap 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
BlogClientclass, 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
BlogServiceTestclass, 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 testThe 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.