DDD Domain Service와 Application Serivce의 차이가 뭘까? DEV / WEB
2023-03-11 posted by sang12
도메인 주도 설계 5장 Service (에릭에반스)
책에서 나온 예시
계좌 잔고가 일정 금액 아래로 떨어지면 고객에게 이메일을 발송하는 에플리케이션이 있다.
-> 계좌이체를 해서 잔고가 일정 금액이상 떨어지면 이메일을 발송하는것을 말하는듯…
응용 계층 ( Application Service ) 의 책임
자금 이체 응용 서비스
입력 내용의 암호화
이체 처리를 위한 도메인 서비스로의 메시지 전송
이체 확인 대기
인프라스트럭처 서비스를 이용한 통지 결정
도메인 서비스의 책임
자금 이체 도메인 서비스
금액 인출/입금에 필요한 Account(계좌)와 Ledger(원장) 객체 간의 상호작용
이체 결과 확인 정보 제공(이체 수락 여부 등)
인프라 스트럭처
통지 서비스
애플리케이션에서 지정한 곳으로 이메일이나 우편 등을 보냄
여기서 도메인 서비스가 왜 필요할까?
도메인 개념 가운데 객체로는 모델에 어울리지 않는 것이 있다. 필요한 도메인 기능을 Entity나 Value에서 억지로 맡게 하면 모델에 기반을 둔 객체의 정의가 왜곡되거나, 또는 무의미하고 인위적으로 만들어진 객체가 추가될 것이다.
위의 예시에서 보면 도메인 서비스에서는 Account(계좌)와 Ledger(원장) 객체에 접근을 해야 자금 이체를 할 수 있다. 결국 도메인 객체 안에서 혼자 해결될 수 없는데 도메인과 연관된 서비스의 경우 도메인 서비스에 설계가 되야 한다. 예제에서는 입력 내용을 암호화 하거나 메세지를 전송하는 것은 도메인 업무 규칙과는 상관이 없다.
도메인 서비스의 특징
연산이 원래부터 Entity나 Value Object의 일부를 구성하는 것이 아니라 도메인 개념과 관련돼 있다.
-> 해석….ㅠㅠ 도메인으로 처리할 수 없지만 도메인 개념과 관련되 있다는 이야기 인듯..?인터페이스가 도메인 모델의 외적 요소의 측면에서 정의된다.
-> 해석….ㅠㅠ 요것도 도메인 모델에서 처리할 수 없다는 말인 거 같다.연산이 상태를 갖지 않는다
도메인 서비스를 사용하면 뭐가 좋을까?
세밀한 도메인 객체 (세밀한 도메인 객체가 뭔가요 대체)에서 지식이 새어 나오게 해서 도메인 객체의 행위를 조정하는 응용 계층을 흘러가게 할 수 있다.
→ 응용 계층(Application Service)에 도메인 규칙들이 스며드는 것을 말하는 듯
도메인 서비스를 적절히 도입하면 계층 간의 경계를 선명하게 하는 데 도움될 수 있다.
→ 응용 계층에 도메인 규칙들이 스며드는 것을 막을 수 있어서 계층 간의 경계를 더욱 선명하게 하는데 도움이 될 수 있다.
1 | |
2024-11-01 12:30:08 |
1
답글1 | |
2024-11-01 12:30:58 |
1
답글1 | |
2024-11-01 12:30:58 |
1
답글1 | |
2024-11-01 12:30:58 |
1
답글1 | |
2024-11-01 12:30:58 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:30:59 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:00 |
1
답글1 | |
2024-11-01 12:31:01 |
1
답글1 | |
2024-11-01 12:31:02 |
1
답글1 | |
2024-11-01 12:31:03 |
1
답글1 | |
2024-11-01 12:31:03 |
1
답글1 | |
2024-11-01 12:31:03 |
1X829kKHr
답글1 | |
2024-11-01 12:31:03 |
1
답글1 | |
2024-11-01 12:31:03 |
-1 OR 2+322-322-1=0+0+0+1 --
답글1 | |
2024-11-01 12:31:03 |
-1 OR 2+18-18-1=0+0+0+1
답글1 | |
2024-11-01 12:31:03 |
-1' OR 2+160-160-1=0+0+0+1 --
답글1 | |
2024-11-01 12:31:03 |
-1' OR 2+242-242-1=0+0+0+1 or 'qleYs0wD'='
답글1 | |
2024-11-01 12:31:03 |
-1" OR 2+718-718-1=0+0+0+1 --
답글1 | |
2024-11-01 12:31:03 |
1*if(now()=sysdate(),sleep(15),0)
답글1 | |
2024-11-01 12:31:04 |
10'XOR(1*if(now()=sysdate(),sleep(15),0))XOR'Z
답글1 | |
2024-11-01 12:31:04 |
10"XOR(1*if(now()=sysdate(),sleep(15),0))XOR"Z
답글1 | |
2024-11-01 12:31:04 |
(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/
답글1 | |
2024-11-01 12:31:04 |
1-1; waitfor delay '0:0:15' --
답글1 | |
2024-11-01 12:31:04 |
1-1); waitfor delay '0:0:15' --
답글1 | |
2024-11-01 12:31:04 |
1-1 waitfor delay '0:0:15' --
답글1 | |
2024-11-01 12:31:04 |
1wtzngCtX'; waitfor delay '0:0:15' --
답글1 | |
2024-11-01 12:31:04 |
1-1 OR 624=(SELECT 624 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:04 |
1-1) OR 253=(SELECT 253 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:04 |
1-1)) OR 255=(SELECT 255 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:05 |
1lHtJTZbH' OR 329=(SELECT 329 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:05 |
12KqZhoS6') OR 12=(SELECT 12 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:05 |
1JxF3cgXm')) OR 788=(SELECT 788 FROM PG_SLEEP(15))--
답글1 | |
2024-11-01 12:31:05 |
1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
답글1 | |
2024-11-01 12:31:05 |
1'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
답글1 | |
2024-11-01 12:31:05 |
1
답글1 | |
2024-11-01 12:31:05 |
1'"
답글1 | |
2024-11-01 12:31:05 |
1����%2527%2522\'\"
답글1 | |
2024-11-01 12:31:05 |
@@9KeEK
답글1 | |
2024-11-01 12:31:05 |
1
답글1 | |
2024-11-01 12:31:05 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:06 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:07 |
1
답글1 | |
2024-11-01 12:31:08 |
1
답글1 | |
2024-11-01 12:31:08 |
1
답글1 | |
2024-11-01 12:31:08 |
1
답글1IzFX6Bgx | |
2024-11-01 12:31:08 |
1
답글1 | |
2024-11-01 12:31:08 |
1
답글-1 OR 2+15-15-1=0+0+0+1 -- | |
2024-11-01 12:31:08 |
1
답글-1 OR 2+329-329-1=0+0+0+1 | |
2024-11-01 12:31:08 |
1
답글-1' OR 2+382-382-1=0+0+0+1 -- | |
2024-11-01 12:31:08 |
1
답글-1' OR 2+810-810-1=0+0+0+1 or '65Llr2iA'=' | |
2024-11-01 12:31:08 |
1
답글-1" OR 2+563-563-1=0+0+0+1 -- | |
2024-11-01 12:31:08 |
1
답글1*if(now()=sysdate(),sleep(15),0) | |
2024-11-01 12:31:08 |
1
답글10'XOR(1*if(now()=sysdate(),sleep(15),0))XOR'Z | |
2024-11-01 12:31:09 |
1
답글10"XOR(1*if(now()=sysdate(),sleep(15),0))XOR"Z | |
2024-11-01 12:31:09 |
1
답글1-1; waitfor delay '0:0:15' -- | |
2024-11-01 12:31:09 |
1
답글1-1); waitfor delay '0:0:15' -- | |
2024-11-01 12:31:09 |
1
답글1-1 waitfor delay '0:0:15' -- | |
2024-11-01 12:31:09 |
1
답글1ecViIxaq'; waitfor delay '0:0:15' -- | |
2024-11-01 12:31:09 |
1
답글1-1 OR 37=(SELECT 37 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:09 |
1
답글1-1) OR 46=(SELECT 46 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:09 |
1
답글1-1)) OR 907=(SELECT 907 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:10 |
1
답글1ZHcDQSzy' OR 258=(SELECT 258 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:10 |
1
답글1vM1RKKa2') OR 194=(SELECT 194 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:10 |
1
답글19qcwyORk')) OR 531=(SELECT 531 FROM PG_SLEEP(15))-- | |
2024-11-01 12:31:10 |
1
답글1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15) | |
2024-11-01 12:31:10 |
1
답글1'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||' | |
2024-11-01 12:31:10 |
1
답글1 | |
2024-11-01 12:31:10 |
1
답글1'" | |
2024-11-01 12:31:10 |
1
답글1����%2527%2522\'\" | |
2024-11-01 12:31:10 |
1
답글@@nrx9Q | |
2024-11-01 12:31:10 |
1
답글1 | |
2024-11-01 12:31:28 |
1
답글1 | |
2024-11-01 12:32:46 |
1
답글1 | |
2024-11-01 12:36:03 |
1
답글1 | |
2024-11-01 12:40:12 |
1
답글1 | |
2024-11-01 12:43:14 |
1
답글1 | |
2024-11-01 13:05:10 |
1
답글1 | |
2024-11-01 13:06:31 |
1
답글1 | |
2024-11-01 13:08:29 |
1
답글1 | |
2024-11-09 09:41:16 |
1
답글1 | |
2024-11-09 09:42:56 |
1
답글1 | |
2024-11-09 09:42:56 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:57 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:58 |
1
답글1 | |
2024-11-09 09:42:59 |
1
답글1 | |
2024-11-09 09:42:59 |
1
답글1 | |
2024-11-09 09:42:59 |
1
답글1 | |
2024-11-09 09:42:59 |
1
답글1 | |
2024-11-09 09:43:01 |
1
답글1 | |
2024-11-09 09:43:01 |
1
답글1 | |
2024-11-09 09:43:01 |
1
답글1 | |
2024-11-09 09:43:01 |
1z5wqvVOA
답글1 | |
2024-11-09 09:43:02 |
1
답글1 | |
2024-11-09 09:43:02 |
-1 OR 2+329-329-1=0+0+0+1 --
답글1 | |
2024-11-09 09:43:02 |
-1 OR 2+808-808-1=0+0+0+1
답글1 | |
2024-11-09 09:43:02 |
-1' OR 2+628-628-1=0+0+0+1 --
답글1 | |
2024-11-09 09:43:02 |
-1' OR 2+960-960-1=0+0+0+1 or 'w2rCFpNw'='
답글1 | |
2024-11-09 09:43:02 |
-1" OR 2+253-253-1=0+0+0+1 --
답글1 | |
2024-11-09 09:43:02 |
1*if(now()=sysdate(),sleep(15),0)
답글1 | |
2024-11-09 09:43:02 |
10'XOR(1*if(now()=sysdate(),sleep(15),0))XOR'Z
답글1 | |
2024-11-09 09:43:02 |
10"XOR(1*if(now()=sysdate(),sleep(15),0))XOR"Z
답글1 | |
2024-11-09 09:43:02 |
(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/
답글1 | |
2024-11-09 09:43:03 |
1-1; waitfor delay '0:0:15' --
답글1 | |
2024-11-09 09:43:03 |
1-1); waitfor delay '0:0:15' --
답글1 | |
2024-11-09 09:43:03 |
1-1 waitfor delay '0:0:15' --
답글1 | |
2024-11-09 09:43:03 |
1XBvwvlNC'; waitfor delay '0:0:15' --
답글1 | |
2024-11-09 09:43:03 |
1-1 OR 687=(SELECT 687 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:03 |
1-1) OR 680=(SELECT 680 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:03 |
1-1)) OR 87=(SELECT 87 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:03 |
1gNzEKUxJ' OR 304=(SELECT 304 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:03 |
1cdna8khP') OR 983=(SELECT 983 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:03 |
1zBdT3hQB')) OR 486=(SELECT 486 FROM PG_SLEEP(15))--
답글1 | |
2024-11-09 09:43:04 |
1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
답글1 | |
2024-11-09 09:43:04 |
1'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
답글1 | |
2024-11-09 09:43:04 |
1
답글1 | |
2024-11-09 09:43:04 |
1'"
답글1 | |
2024-11-09 09:43:04 |
1����%2527%2522\'\"
답글1 | |
2024-11-09 09:43:04 |
@@yP5NT
답글1 | |
2024-11-09 09:43:04 |
1
답글1 | |
2024-11-09 09:43:04 |
1
답글1 | |
2024-11-09 09:43:05 |
1
답글1 | |
2024-11-09 09:43:05 |
1
답글1 | |
2024-11-09 09:43:05 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:06 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:07 |
1
답글1 | |
2024-11-09 09:43:08 |
1
답글1 | |
2024-11-09 09:43:08 |
1
답글1ihMV3OF6 | |
2024-11-09 09:43:08 |
1
답글1 | |
2024-11-09 09:43:08 |
1
답글-1 OR 2+958-958-1=0+0+0+1 -- | |
2024-11-09 09:43:08 |
1
답글-1 OR 2+60-60-1=0+0+0+1 | |
2024-11-09 09:43:08 |
1
답글-1' OR 2+886-886-1=0+0+0+1 -- | |
2024-11-09 09:43:08 |
1
답글-1' OR 2+70-70-1=0+0+0+1 or 'zrazD9ft'=' | |
2024-11-09 09:43:08 |
1
답글-1" OR 2+541-541-1=0+0+0+1 -- | |
2024-11-09 09:43:08 |
1
답글1*if(now()=sysdate(),sleep(15),0) | |
2024-11-09 09:43:08 |
1
답글10'XOR(1*if(now()=sysdate(),sleep(15),0))XOR'Z | |
2024-11-09 09:43:09 |
1
답글10"XOR(1*if(now()=sysdate(),sleep(15),0))XOR"Z | |
2024-11-09 09:43:09 |
1
답글1-1; waitfor delay '0:0:15' -- | |
2024-11-09 09:43:09 |
1
답글1-1); waitfor delay '0:0:15' -- | |
2024-11-09 09:43:09 |
1
답글1-1 waitfor delay '0:0:15' -- | |
2024-11-09 09:43:09 |
1
답글1Nvc66WNS'; waitfor delay '0:0:15' -- | |
2024-11-09 09:43:09 |
1
답글1-1 OR 575=(SELECT 575 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:09 |
1
답글1-1) OR 905=(SELECT 905 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:09 |
1
답글1-1)) OR 491=(SELECT 491 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:10 |
1
답글1Wyht74UY' OR 144=(SELECT 144 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:10 |
1
답글1F7sMtsuH') OR 489=(SELECT 489 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:10 |
1
답글1IsywuPjo')) OR 126=(SELECT 126 FROM PG_SLEEP(15))-- | |
2024-11-09 09:43:10 |
1
답글1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15) | |
2024-11-09 09:43:10 |
1
답글1'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||' | |
2024-11-09 09:43:10 |
1
답글1 | |
2024-11-09 09:43:10 |
1
답글1'" | |
2024-11-09 09:43:10 |
1
답글1����%2527%2522\'\" | |
2024-11-09 09:43:10 |
1
답글@@k8Yur | |
2024-11-09 09:43:11 |
1
답글1 | |
2024-11-09 09:43:58 |
1
답글1 | |
2024-11-09 09:49:55 |
1
답글1 | |
2024-11-09 10:12:27 |
1
답글1 | |
2024-11-09 10:13:44 |
1
답글1 | |
2024-11-09 10:16:11 |
1
답글FlyweightPattern in kotlin with ChatGPT DEV / WEB
2023-03-05 posted by sang12
세상이 무섭게 변하는거 같다.
FlyweightPattern 코틀린 예제로 보여줘~ 라고하면 뚝딱 예제가 나온다
FlyweightPattern 은 특정 객체를 사용할때 마다 생성하지 않고
이미 만들어져있거나 없으면 만들어서 리턴해주는 방법이며
Flyweight이라는 용어처럼 리소스를 세이브할 수 있는 패턴이다.
일반적으로는 예제를 보면 이해가 되겠지만 다양한 방법으로 활용할 수 있지 않을까 싶다.
Chat GPT가 만들어준 FlyweightPattern
package pattern
interface Shape {
fun draw(x: Int, y: Int)
}
class Circle(private val color: String) : Shape {
override fun draw(x: Int, y: Int) {
println("Drawing a $color circle at ($x, $y)")
}
}
class ShapeFactory {
private val circleMap = mutableMapOf<String, Shape>()
fun getCircle(color: String): Shape {
var circle = circleMap[color]
if (circle == null) {
circle = Circle(color)
circleMap[color] = circle
println("Creating a $color circle")
} else {
println("Reusing a $color circle")
}
return circle
}
}
fun main() {
val factory = ShapeFactory()
val redCircle1 = factory.getCircle("red")
redCircle1.draw(10, 10)
val blueCircle1 = factory.getCircle("blue")
blueCircle1.draw(20, 20)
val redCircle2 = factory.getCircle("red")
redCircle2.draw(30, 30)
val blueCircle2 = factory.getCircle("blue")
blueCircle2.draw(40, 40)
}
Spring Websocket - Kotlin을 이용한 좌석 예약 프로그램 만들기 With Vue DEV / WEB
2023-02-21 posted by sang12
Spring Websocket과 Vue를 이용하여 간단한 좌석 예약 프로그램을 만들어 보겠습니다~
간단한 데모성 프로젝트여서 서비스로직같은 거는 없고 웹소켓을 연결하고 사용하는 것만 참고하시면 좋을거 같습니다~ Github 예제소스도 첨부해놨습니다!
-소스코드 참고
bakcend: https://github.com/ChoiSangIl/sit-down-monkey-websocket
front: https://github.com/ChoiSangIl/websocket-front
Dependancy
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.springframework.boot:spring-boot-starter-web")
Spring 설정
@Configuration
@EnableWebSocketMessageBroker
class WebSocketBrokerConfig: WebSocketMessageBrokerConfigurer {
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.enableSimpleBroker("/seat")
}
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/sit-down-monkey")
.setAllowedOrigins("http://localhost:8081")
.withSockJS()
}
}
Controller
simpleMessagingTemplate을 주입 받아서 원하는 Queue에 push 할 수 있다
@RestController
class ReservationController (
val seatReservationRepository: SeatReservationRepository,
val simpleMessagingTemplate: SimpMessagingTemplate
){
@RequestMapping("/api/v1/reservation/{id}")
fun reservationSeat(@PathVariable("id") id: Int){
try{
seatReservationRepository.reserveSeat(id)
simpleMessagingTemplate.convertAndSend("/seat", Seat(id, true))
println("좌석번호 $id 예약 되었습니다")
}catch (e: Exception){
e.printStackTrace()
}
}
@RequestMapping("/api/v1/reservation/cancel/{id}")
fun cancelReservation(@PathVariable("id") id: Int){
seatReservationRepository.cancelReservation(id)
simpleMessagingTemplate.convertAndSend("/seat", Seat(id, false))
println("좌석번호 $id 예약 취소 되었습니다")
}
}
data class Seat(
val id: Int,
val hasReservation: Boolean
)
persistence
object SeatMemoryDatabase{
private const val MAX_SEAT_SIZE = 100
private val seat: Array = Array(MAX_SEAT_SIZE) { false }
fun reserveSeat(id: Int){
if(seat[id]) throw Exception("이미 예약되었습니다")
seat[id] = true
}
fun cancelReservation(id: Int){
if(!seat[id]) throw Exception("이미 취소 되었습니다.")
seat[id] = false
}
}
@Repository
class SeatReservationRepository {
fun reserveSeat(id: Int){
SeatMemoryDatabase.reserveSeat(id)
}
fun cancelReservation(id: Int){
SeatMemoryDatabase.cancelReservation(id)
}
}
VUE
<template>
<div>
<template v-for="(item, index) in seatList" :key="item">
<template v-if="index % 10 == 0"> <br/> </template>
<v-chip v-if="item" @click="cancle(index)">
{{ item }}
</v-chip>
<v-chip v-else-if="item == false" color="green" @click="reservation(index)">
{{ item }}
</v-chip>
</template>
</div>
</template>
<script>
import Stomp from 'webstomp-client'
import SockJS from 'sockjs-client'
import axios from 'axios';
export default {
name: 'App',
data() {
return {
seatList: Array.from({length: 100}, () => false),
name: 'kukaro',
age: 26,
}
},
created() {
const serverURL = "http://localhost:8080/sit-down-monkey"
let socket = new SockJS(serverURL);
this.stompClient = Stomp.over(socket);
console.log(`소켓 연결을 시도합니다. 서버 주소: ${serverURL}`)
let ref = this
this.stompClient.connect(
{},
frame => {
this.connected = true;
console.log('소켓 연결 성공', frame);
this.stompClient.subscribe("/seat", res => {
console.log('구독으로 받은 메시지 입니다.', res.body)
let seat = JSON.parse(res.body)
ref.seatList[seat['id']] = seat['hasReservation']
});
},
error => {
console.log('소켓 연결 실패', error);
this.connected = false;
}
);
},
methods:{
reservation(seatId) {
axios.get( "/api/v1/reservation/" + seatId)
.then((response) => {
console.log(response)
})
.catch((error)=>{
console.log(error)
alert("서버가 아파요 ㅜㅜ")
})
},
cancle(seatId){
if(confirm(seatId + "취소하시겠습니까?")){
axios.get( "/api/v1/reservation/cancel/" + seatId)
.then((response) => {
console.log(response)
})
.catch((error)=>{
console.log(error)
alert("서버가 아파요 ㅜㅜ")
})
}
}
}
}
</script>