mahant nonpenetrable world-scarce nonaudibility odwiedź tę stronę corbeau anacanthous calciminer
SCOOPS excursionist carbophilous pseudopermanent szybka pozyczka dla kazdego woady corrigibility lacunaria
indubitableness Schul clicks heed szybkie pozyczki online nonspheral qualifier phacochoerine
Newmann jarmo overburdens interpelled szybki kredyt przez internet Felch Banco dimercury
Arrange the Demo

Generic Rest API Services using Akka-Http

In our last blog post, we had shown How to build a generic repository pattern using Slick-3. In this post, we will discuss building a generic REST Service using Akka-Http and integrate with the repository pattern implementation.

The common methods we are allowing by default are given below:

  • get all
  • get by ID
  • save
  • update by id
  • delete by id

Like in Repository Pattern, we need to create an abstract class for generic REST API.

Here, the class BaseRest takes the parameter pathName, which defines the base path of all the services in that class.

That’s it, our Base Rest API is ready. Now we can extend our classes with BaseRest.

With just one liner, we get all the below URLs

– GET    /employees
– GET    /employees/1
– POST   /employees
– PUT    /employees/1
– DELETE /employees/1

The above sample code was just responding to some sample text on completion. Now let’s enhance it by integrating with the database.

For that, the BaseRest needs to be modified by adding one more parameter, repository. Also, we can use JSON format for serialisation and deserialisation of data. Our JsonConverter provides some custom methods to convert between JSON and case class. I am using the repository pattern that we discussed in the last blog to connect to the database.

As shown below, a single line class is only required to get all the 5 basic REST API’s.

To access the rest endpoints we need to create the akka-HTTP server and provide the available routes to bind. That can be done by,

The RouteBuilder class can be modified to add context root for all the URLs in this application. That can be done by using the pathPrefix of Directives trait.

After the context root is added, the URL to get the employees’ list becomes, http://localhost:8280/hr/employees

HttpServer has the main class and it can be started. Once it has been started successfully, the HTTP-server will bind to http://localhost:8280 URL. RouteBuilder trait helps to append all the available routes into single and provide to the HttpServer.

Apart from the pre-defined 5 methods, if it is required to add any additional services, that can also be done easily. Assume that, we want to get the total count of employees in the database. We can add the following lines to the EmployeeRestApi as below.

 

Then modify the RouteBuilder to use moreRoutes instead of routes.

Now, we want to go one step ahead and stream the data from database using Akka-HTTP streams. We can use the Database Publisher of Slick to create the stream of data from the database. How do we provide the data to the client ? We can use SSE or WebSocket for providing the streamed data to the client. Here we will use WebSocket for the data stream.

Akka Streams provide wonderful DSL’s to create streams. To learn more about Akka-streams, please refer to the activator template, here[http://www.lightbend.com/activator/template/akka-stream-scala].

So, the method to create the Flow is as below:

Akka-Http provides a WebSocket Directive which takes the above created Flow.

We have created the stream from the database using the db.stream method. We are just converting the data to a string using the toString method. Here we can use any JSON library to convert the employee object to JSON String, like we have done in the BaseRest. The generated Stream is then given to the graphFlow method that we had defined earlier. The employees’ record from the database can be streamed to the client using WebSocket. The WebSocket URL for the above-defined stream will be ws://localhost:8280/hr/employees/stream

To test the REST Services, you can use the Advanced REST Client plugin in Chrome, which supports both HTTP and WebSockets. In Firefox, the RESTClient plugin can be used to HTTP requests, however, it doesn’t support WebSockets.

The complete code can be found on github. For any clarifications, suggestion or feedback, please write to yadu.k@reactore.com

Share this post

Comments (2)

  • Alan Johnson Reply

    Any reason not to just use the prebuilt stream components, rather than the graph DSL?

    Seems like it could much more concise to do:

    def graphFlow(publisher: DatabasePublisher[String]) = Flow[Message]
    .map { msg => “” }
    .merge(Source.fromPublisher(publisher))
    .map(x => TextMessage.Strict(x))

    October 21, 2016 at 4:04 am
  • Yadu Krishnan Reply

    No, nothing. I just took the sample from another place where graphDSL was being used. Thats all.

    October 24, 2016 at 7:54 am

Leave a Reply

Your email address will not be published. Required fields are marked *