i'm trying figure out options have architecture of api project.
i create api using jax-rs version 1.0. api consumes remote ejbs (ejb 3.0) bigger, old , complex application. i'm using java 6.
so far, can , works. i'm not satisfied solution. see packages disposition. concerns described after code:
/api/ /com.organization.api.v1.rs -> rest services jax-rs annotations /com.organization.api.v1.services -> service classes used rest services. basically, have logic transform dtos objects remote ejbs in json. separated api version, because json can different in each version. /com.organization.api.v1.vo -> view objects returned rest services. transformed in json using gson. /com.organization.api.services -> service classes used versioned services. here have lookup remote ejbs , api logic, validations. services can used versioned of each service.
example of com.organization.api.v1.rs.userv1rs
:
@path("/v1/user/") public class userv1rs { @get public userv1vo getusername() { userv1vo uservo = servicelocator.get(userv1service.class).getusername(); return uservo; } }
example of com.organization.api.v1.services.userv1service
:
public class userv1service extends userservice { public userv1vo getusername() { userdto userdto = getusername(); // method userservice return new userv1vo(userdto.getname); } }
example of com.organization.api.services.userservice
:
public class userservice { public userdto getusername() { userdto userdto = remoteejblocator.lookup(userremote.jndi_remote_name).getuser(); return userdto; } }
some requirements of project:
- the api have versions: v1, v2, etc.
- the different api versions of same versioned service can share code:
userv1service
,userv2service
usinguserservice
. - the different api versions of different versioned services can share code:
userv1service
,orderv2service
usinganotherservice
. - each version have own view object (
userv1vo
, notuservo
).
what botters me code above:
- this
servicelocator
class not approach me. class use legacy code old library , have lot of questions how class works. way useservicelocator
strange me , strategy not mock services for unit tests. create new servicelocator or use dependency injection strategy (or better approach). - the
userservice
class not intended used "external" service,orderservice
. it'suservxservice
. in future, maybeorderservice
use codeuserservice
... - even if ignore last problem, using
servicelocator
need lot oflookups
among code. chance of create cyclic dependency (serviceone lookup servicetwo lookup servicethree lookup serviceone) high. - in approach, vos,
userv1vo
, used in unversioned services (com.organization.api.services
), cannot happen. architecture don't allow not allowed. have idea create new project,api-services
, putcom.organization.api.services
there avoid this. solution?
so... ideas?
a couple of things see:
the
userservice
should ideally based off interface. seem have similar contract, difference sources (remoteejb, localservicelocator). these should returning dtosuserv1service extends userservice
should not use inheritance should instead favour composition. think you'd need v2 of same service. based on example, you'duserv2service extends userservice
. not ideal if end abstract methods in base class specific 1 version. of sudden other versioned services need cater this.
for servicelocator
you're better off using dependency injection framework spring or perhaps cdi in case. apply own code if project new.
for ones hard unit test, you'd wrap remoteejb calls it's own interface makes easier mock out. tests remoteejbs integration tests project.
the userservice class not intended used "external" service, orderservice. it's uservxservice. in future, maybe orderservice use code userservice
there nothing wrong services on same layer talk each other.
in approach, vos, userv1vo, used in unversioned services (com.organization.api.services), cannot happen. architecture don't allow not allowed. have idea create new project, api-services , put com.organization.api.services there avoid this. solution?
just because "could" doesn't mean should. while might seem idea separate layer it's own project; in reality nothing stops developer either recreating same class in project or including jar in classpath , using same class. i'm not saying splitting wrong, should split right reasons instead of "what if scenarios".
Comments
Post a Comment