我有RESTful API,只处理SQL Server数据库。 API方法接受JSON字符串。此字符串是EF Entity的精确表示。想法是将字符串转换为实体并保存它。
下面的代码行[HttpPost]
public void ApiMethod([FromBody] string request)
{
var doc = JsonConverter.DeserializeObject<Document>(request);
_dbContext.Documents.Add(doc);
_dbContext.SaveChanges();
}
我想知道将实体结构暴露给外部客户端是否可以?
替代方法是
方法1:将json字符串转换为动态,并通过映射属性构建所需的实体。
[HttpPost]
public void ApiMethod([FromBody] string request)
{
dynamic anonymousDoc = JsonConverter.DeserializeObject(request);
var doc = new Document()
{
Property1 = anonymousDoc.Property1,
Property2 = anonymousDoc.Property2
}
_dbContext.Documents.Add(doc);
_dbContext.SaveChanges();
}
方法2:创建强类型DTO
[HttpPost]
public void ApiMethod([FromBody] string request)
{
var dto = JsonConverter.DeserializeObject<DocumentDTO>(request);
var doc = new Document()
{
Property1 = dto.Property1,
Property2 = dto.Property2
}
_dbContext.Documents.Add(doc);
_dbContext.SaveChanges();
}
但是我必须在这里创建大量具有相同属性的DTO。
问题1:这里推荐的方法是什么?
问题2:(此问题与问题1有关,所以我在此处发帖而不是创建新帖子。)我提到的API以上是微服务架构的一部分。我有一堆微服务,通过HTTP相互通信。由于所有服务彼此分离,因此没有强类型数据合同。所以我虽然传递JSON将是一个很好的方法。我使用Newtonsoft.json
进行序列化/反序列化,因为它具有比microsoft的本机DataContractJsonSerializer更好的性能。
再次是这种在微服务之间进行通信的正确方法。
答案 0 :(得分:0)
我想知道可以将实体结构暴露给外部 客户端?
通过直接在服务边界上展示您的实体结构,您在某种程度上每隔tenet of SOA就会破坏一次。
这些原则是有原因的:保护你免受痛苦。您可能遭受这种方法的痛苦包括但不限于:
方法1:将json字符串转换为动态并构建所需的 实体通过映射属性。
根据您的具体要求,您可能有理由使用此方法。例如,如果您所做的只是通过http公开基本上是数据库驱动程序,那么这种方法可能很好。
然而,这实际上并没有解决任何痛点,因此与您原来的方法类似。
方法2:创建强类型DTO
这是一种更好的方法,但只是轻微的 - 它解决了上面的痛点1和2,但对3和4没有任何作用。我建议对这种方法进行调整,以解决这些问题:
方法3:创建强类型DTO并直接公开它。
[HttpPost]
public void DoSomethingWithDocument([FromBody] DocumentDTO docDto)
{
// map from docDto to docEntity
...
_dbContext.Documents.Add(docEntity);
_dbContext.SaveChanges();
}
由于所有服务彼此分离,因此没有 强类型数据合同。
通过拒绝分享合同来避免耦合是没有意义的。明确定义的合同是解耦服务的最佳方式之一。
我正在使用Newtonsoft.json进行序列化/反序列化 比微软的本地人有更好的表现 DataContractJsonSerializer
如果你发现自己完全偏离了一条经过良好探索的道路,为了合并一种特定的工具或技术,除了表现之外别无其他原因,我会非常小心。可以是premature optimisation。