2017-06-27 2 views
1

premier notre scénario:comment publier plusieurs points d'extrémité de repos avec la même adresse de base?

nous avons un environnement OSGi, où plusieurs faisceaux publient leur propre point final de repos, par exemple:

http://localhost:8080/api/cars 
http://localhost:8080/api/food 
http://localhost:8080/api/toys 

Cela a été fait en utilisant la méthode JAXRSServerFactoryBean.create(), avec adresse étant ceux énumérés ci-dessus.

Maintenant, nous devons ajouter un identifiant de locataire aux demandes des utilisateurs (pas l'autorisation de l'utilisateur, ce qui est différent, car les utilisateurs peuvent faire partie de plusieurs locataires). URL doivent ressembler à ceci:

http://localhost:8080/api/tenant/{tenantid}/cars 
http://localhost:8080/api/tenant/{tenantid}/food 
http://localhost:8080/api/tenant/{tenantid}/toys 

J'ai essayé deux approches pour y parvenir maintenant:

  1. Ajouter locataire-id adresse du service (http://localhost:8080/api/tenant/{tenantid}) - Résultat: Je pourrais accéder à mon service sous l'URL donnée, mais je n'ai pas pu remplir de données pour tenantid mais j'ai dû taper {tenantid} dans l'URL, ce qui n'est pas la façon dont j'ai besoin de l'utiliser.
  2. Publish les trois services sous la même URL (http://localhost:8080/api) le déplacement du locataire-partie à l'annotation @Path de chaque classe api - Résultat: Exception, cette adresse était déjà pris par un autre critère d'évaluation

Est-ce Quelqu'un at-il une idée, comment cela peut-il être fait correctement? Je sais que le ServiceBean peut prendre un ensemble d'implémenteurs en tant qu'argument au lieu d'une seule classe, mais ce n'est pas une option, car les paquets se chargent séparément et j'ai eu quelques problèmes de dépendances, quand j'ai essayé de faire "tout en un". En tant que sidenote: je sais, nous pourrions mettre l'identifiant du locataire dans un en-tête, mais généralement l'information du locataire est quelque part dans une URL (hôte ou chemin) et nous voulons aller avec ce style "commun" au lieu d'ajouter un en-tête personnalisé , bien que l'implémentation du style d'en-tête soit beaucoup plus facile (ça marche déjà).

Toutes les idées seraient utiles. Merci, Kay

+0

d'autres idées? nous sommes sur le point de le faire en utilisant des paramètres de requête, ce que nous essayions d'éviter ... –

Répondre

0

Essayez quelque chose comme:

@Path("/tenants") 
public class TenantResource{ 

    @Path("/{tenantId}/cars") 
    @Get 
    public List<Car> getTenantCars(@PathParam("tenantId") long tenantId){...} 

    @Path("/{tenantId}/food") 
    @Get 
    public Food getTenantFood(@PathParam("tenantId") long tenantId){...} 

    @Path("/{tenantId}/toys") 
    @Get 
    public List<Toy> getTenantToys(@PathParam("tenantId") long tenantId){...} 
} 

Si vous avez des URL telles que les locataires/{TenantID}/voitures cela signifie généralement "les voitures du locataire id = TenantID". "Voitures" est une propriété de la ressource "locataire" et devrait donc se trouver dans la même ressource. Je pense qu'il pourrait être difficile de modulariser les propriétés d'une ressource/d'un objet.

Mais vous pourriez envisager une ressource "voiture" et interroger la ressource comme:/voitures TenantID = {} TenantID

@Path("/cars") 
public class CarResource{ 

    @Get 
    public List<Car> getCarsByTenantId(@QueryParam("tenantId") long tenantId){...} 

} 

ou similaire.

+0

Je sais que ces solutions fonctionneraient, mais mes points finaux étaient juste quelques exemples et "voitures" est la racine de CRUD ops ainsi que des informations plus détaillées - quelque chose comme/voitures/capteurs/température/ou/voitures/pneus/pression - suspendre toutes ces choses sous "/ locataires" ferait sauter votre classe TenantResource proposée pour aimer 60+ méthodes (par opposition à chacune des 3 classes de ressources simples ... Comme pour la requête param: Comme je l'ai dit il y a aussi CRUD ops, y compris POST, DELETE et PUT, ainsi les paramètres de requête ne sont pas une option. –