API와 응용 프로그램간에 객체를 공유하는 패턴


9

웹 응용 프로그램의 디자인에 대해 심각한 의문이 있습니다.

비즈니스 로직을 인터페이스와 분리하고 싶었으므로 데이터베이스에 대한 모든 요청을 처리하는 웹 API를 만들었습니다.

엔터티 프레임 워크와 작업 단위 및 일반 리포지토리 패턴이있는 ASP.NET 웹 API입니다. 지금까지 모든 것이 좋습니다.

문제

도움이 필요한 곳은 API와 응용 프로그램간에 객체를 효율적으로 공유하는 방법을 알 수 없다는 것입니다.

엔터티 개체를 직접 직렬화하고 싶지 않습니다. 엔터티 모델이 변경되면 아무런 이유없이 큰 개체를 직렬화 할 수 있기 때문에 나쁜 습관이라고 생각했습니다.

현재 구현 방법

내 인터페이스는 C #의 ASP.NET 웹 응용 프로그램이고 API는 C #이므로 공유하려는 모든 클래스의 정의를 사용하여 공통 라이브러리를 만들었습니다.

안드로이드 앱을 개발할 때 솔루션이 작동하지 않는다는 것을 알고 있습니다 .Java에서 클래스를 다시 만들어야하지만 가장 큰 문제는 아닙니다.

문제는 항상 객체를 변환하는 느낌입니다.

내 작업 흐름의 예는 다음과 같습니다.

모든 폼과 데이터 주석이있는 모델로 시작하여 사용자가 해당 모델을 컨트롤러에 게시합니다.

컨트롤러 에서이 모델을 공통 라이브러리의 클래스로 변환 한 다음 해당 객체를 API로 보내야합니다.

그런 다음 API의 컨트롤러가 호출을 포착하고 해당 객체를 엔티티 객체로 변환하여 데이터베이스를 업데이트합니다.

3 개 수업이 있습니다

  1. 유효성 검사를위한 모든 데이터 주석이있는 뷰 모델 (클라이언트)
  2. 객체를 공유하는 공통 라이브러리 클래스 (DLL)
  3. 엔터티 클래스 (API)

나는 내가 정말로 잘못하고 있다는 느낌이 든다. 더 우아한 것이 있습니까? 프로젝트가 너무 커지기 전에이 문제에 대한 좋은 해결책이 있는지 확인하고 싶습니다.


내 질문이 명확하지 않으면 주저하지 말고 질문하십시오.
Marc

나에게 어떤 아키텍처를 구현했는지 확실하지 않습니다 (아마도 퍼즐을하는 .net 문구 일 것입니다)-클라이언트, 서버, db의 3 계층 아키텍처입니까?
Andy

예, 웹 API를 사용하는 웹 응용 프로그램이 있습니다. API는 데이터베이스에 비즈니스 로직이있는 API입니다.
Marc

답변:


12

데이터베이스 객체, 데이터 전송 객체, 유효성 검사 논리가있는 클라이언트 객체 사이에서 항상 객체를 앞뒤로 변환하는 것처럼 보일 수 있지만 아니요, 잘못한 것은 없습니다. .

이러한 각 개체는 동일한 정보 단위를 나타낼 수 있지만 서로 다른 책임이 있습니다. 데이터베이스 객체는 데이터베이스와의 통신 인터페이스이며 데이터베이스 메타 데이터 주석 및 / 또는 데이터베이스 구현에 대한 불필요한 세부 정보가 있거나 없을 수 있으므로 데이터베이스 계층에 보관해야합니다.

데이터 전송 객체는 API 소비자와의 통신 인터페이스입니다. 다른 언어 / 플랫폼에서 쉽게 사용할 수 있도록 최대한 깨끗해야합니다. 지원하려는 API 소비자에 따라 이러한 모양과 동작에 특정 제한이 적용될 수 있습니다.

유효성 검사 논리가있는 클라이언트 개체는 실제로 API 프로젝트의 일부가 아닌 소비자 프로젝트의 일부입니다. 서버가 알지 못하는 (그리고 알지 말아야 할) 추가 클라이언트 별 로직 (이 경우 유효성 검사 속성)을 추가하므로이 경우에는 데이터 전송 객체와 같을 수 없습니다. 이 객체는 실제로는 아니기 때문에 API의 일부로 계산하십시오. 그것들은 소비자 응용 프로그램에 따라 다르며 API를 소비하는 일부 응용 프로그램은 실제로 이러한 객체를 만들 필요가 없으며 데이터 전송 객체에서만 살아남을 수 있습니다. 예를 들어, 유효성 검사가 필요하지 않은 경우 데이터 전송 개체와 완전히 동일한 추가 개체 계층이 필요하지 않습니다.

나에게는 세 가지 객체 유형 각각이 깨끗한 코딩과 좋은 연습 인 단일 책임에 매우 잘 어울리는 것처럼 보입니다. 안타깝게도, 깨끗한 코드와 모범 사례는 때로는 많은 추가 코드를 작성하고 "후문"으로 추가 후프를 뛰어 넘는 것을 의미합니다. 코딩하는 동안 이것이 제공하는 가치를 이해하기 어려울 수 있습니다. 그러나 응용 프로그램을 릴리스하고 지원하거나 다음 버전의 새로운 기능을 추가하기 시작하면 시간이 걸렸다는 것을 인식하게 될 것입니다 이러한 우려를 우선적으로 분리하십시오. (당신은 말할 것도없고

또한 다른 객체 유형 사이에 변환 코드를 작성하는 것을 싫어하지만 솔루션은 일반적으로 다음 중 하나입니다.

  • C #을 사용하는 경우 환상적인 AutoMapper 라이브러리 ( http://automapper.org/ )를 사용할 수 있습니다 . 나는 이와 같은 다른 라이브러리가 몇 개 있다고 생각하지만 AutoMapper는 지금까지 본 것 중 가장 강력한 라이브러리입니다.
  • 객체 변환에 도움이되는 라이브러리를 찾을 수없는 경우 라이브러리 간 변환을위한 유틸리티 메소드 세트를 작성하십시오. 이것은 짜증이 나지만 장기적으로 가치가 있습니다. 처음으로 변환해야 할 때 변환 방법을 작성하십시오-기다리지 마십시오.

설명해 주셔서 감사합니다.하지만 여전히 이해하기가 어렵습니다. 데이터 전송 계층에 유효성 검사가없는 이유를 모르겠습니다. 다음 모바일 앱에 대한 유효성 검사를 잊어 버린 경우 어떻게합니까? 적어도 데이터베이스 모델에서 예외를 수행하는 대신 API를 호출하면 유효성이 검사되지 않습니다. 잘 모르겠습니다.
Marc

1
API 수준에서 유효성을 검사해서는 안된다는 말은 아닙니다. 솔직히 말해서, 이것이 검증해야 할 가장 중요한 곳입니다. 앱에서 유효성 검사는 사용자가 실수를하지 않도록 도와주는 "좋은 기능"일 뿐이며 데이터 전송 개체를 유효성 검사하는 것은 악의적이고 잘못된 데이터를 차단하기위한 것입니다. 그러나 사용 사례가 다르므로 다른 유효성 검사 프레임 워크를 사용해야 할 수도 있고 (앱과 API가 동일한 언어로 작성되지 않은 경우 다른 유효성 검사 프레임 워크 사용해야 함) 각 수준에서 약간 다른 내용을 유효성 검사 할 수 있습니다 (계속 다음 댓글에서)
wasatz

1
따라서 데이터 전송 객체의 유효성을 검사해야합니다. 그러나 유효성을 검사하는 방식이 실수로 다른 프레임 워크에 대한 종속성을 유발하지 않는지 확인해야합니다 . 물론 앞에서도 언급했듯이 데이터 전송 객체가 전혀 검증되었는지 또는 동일한 프레임 워크에 의해 검증되었는지 확실하지 않으므로 "두 번 검증"해야합니다.
wasatz

2
주로 애플리케이션과 API를 완전히 다른 두 개의 별도 애플리케이션으로보아야합니다. 당신은 동시에 그것들을 개발하고있을 수 있으며 그들은 동일한 Visual Studio 솔루션 / 이클립스 프로젝트에있을 수 있습니다. 그러나 그들은 실제로 완전히 별개의 두 프로그램입니다. 응용 프로그램에서 작업 할 때는 API를 만든 사람임을 "잊어"일반적인 타사 API와 마찬가지로 사용하십시오. 그렇게하면 API를 사용할 때 다른 사람들이 어떻게 느끼는지 더 잘 볼 수 있고 최악의 부분을 조기에 수정할 수 있습니다.
wasatz

1
API 프로젝트에서 작업 할 때도 마찬가지입니다. 많은 타사 개발자가 사용할 서비스를 작성한다고 상상해보십시오. 현재 응용 프로그램에 대해 너무 많이 생각하지 말고 "내가 제공하는 서비스"에 대해 더 많은 생각을하고 API를 사용하는 모든 사람 (자신 포함)이 서버를 죽이고 자하는 악한 사람들이라고 가정하십시오. 전체 데이터베이스를 삭제하십시오.
wasatz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.