简体   繁体   中英

Scala service interface design for a backend server?

Im writing a backend restful api server in Scala Playframework using Slick for database access.

Because my database schema evolves all the time, I decided to generate Slick helper classes via slick-codegen. The Users table is mapped to this Scala case class

case class UserRow(userId: Long, username: String, passwordHash: String,
passwordSalt: String, email: String, firstName: String, ...)

Now my data access consists of 2 layers: Service & DAO

DAO is very simple and allows inserting, deleting etc UserRow's from and to database

Now my problem starts at the Service layer design invoked by the application controllers.

If eg it show(id) method would return an UserRow, I would reveal user's private salt and password hash. On the other hand, this approach would allow me to easily wrap them in and out of JSON.

Another way is for the show method (used just as an example) to return a tuple containing the data, but that would be inconvenient for json transfering.

Also, I could create an additional User class but that would create tons of boilerplate in the long run

What is the right way to handle this situation? Where can I find recommended and smart pattern in the future?

There seems like three concepts that need representation -

  1. The row in the database. This is the UserRow case class you generated and is coupled with your DB. This is the object that should be accepted and returned by your DAOs
  2. The model. This is the abstraction your code should use for implementing business logic. You have the choice of creating a thin model (only fields) with service classes to implement business logic, or thick models with the business logic in methods on the model and the service layer only managing transactions and invoking multiple models.
  3. The API response, ie, the JSON representation of your entity.

All three of these should be separately created. This will ensure that your implementation is decoupled and clean in the long run. This does not mean you'll have 3*number of tables objects floating around. You'll have 1 Row case class for every table, but your model should abstract that out, and possibly represent the logic for many tables. The Json representation may also vary depending on the route and/or caller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM