๐Ÿ’ป Programming/Personal Project (5)

๊ฐœ์ธํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‹ค๋ณด๋ฉด ํ•œ๋™์•ˆ ์ž‘์—…์ง„ํ–‰์„ ๋ชปํ•˜๋‹ค๊ฐ€ ๋‹ค์‹œ ์žฌ๊ฐœํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ

์ด๋•Œ ๋…ธํŠธ๋ถ์„ ์ƒˆ๋กœ ๋ฐ”๊พธ์—ˆ๊ฑฐ๋‚˜, ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ž˜๋ชปํ•ด์„œ ์‚ญ์ œํ–ˆ๋‹ค๊ฐ€

๋‹ค์‹œ git clone ํ•  ๋•Œ Invalid username or password ๋ฅผ ๋ณด๊ฒŒ ๋œ๋‹ค.

github ์—์„œ https ์ฃผ์†Œ๋กœ clone ์„ ํ•˜๊ฑฐ๋‚˜

ํ† ๊ทผ์œ ํšจ๊ธฐ๊ฐ„์„ ๋„˜๊ฒจ์„œ git push๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด

invalid ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

1๋…„์—๋„ ์—ฌ๋Ÿฌ๋ฒˆ ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”๋ฐ

์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š”์ง€ ์ž๊พธ ๊นŒ๋จน์–ด์„œ ๊ธฐ๋ก์šฉ์œผ๋กœ ๋‚จ๊น๋‹ˆ๋‹ค.

Github ๊ณ„์ •์˜ Settings > Developer Settings ๋กœ ๊ฐ€์„œ

Personal Access Token(์ดํ•˜ PAT) ์„ ์žฌ์ƒ์„ฑ(regenerate)ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  git clone ์˜ ๊ฒฝ์šฐ ์•„๋ž˜์ฒ˜๋Ÿผ clone ๋ช…๋ น์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

https://๊ณ„์ •๋ช…:PAT@github.com/ํด๋ก ํ• _repo์˜ ์ฃผ์†Œ

git push ์˜ ๊ฒฝ์šฐ username๊ณผ  password ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๋œจ๊ฒŒ๋˜๋Š”๋ฐ

์ด๋•Œ password ์— github ์›น ๋กœ๊ทธ์ธ์‹œ ์ž…๋ ฅํ•˜๋Š” password ๊ฐ€ ์•„๋‹Œ PAT ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค. 

reactjs ํ”„๋ก ํŠธ์™€ java ๋ฐฑ์—”๋“œ ์—ฐ๋™

์ด๋ฒˆ์—๋Š” ReactJS๋กœ ๊ตฌํ˜„ํ•œ ํ”„๋ก ํŠธ์—”๋“œ์™€ Java + ์Šคํ”„๋ง๋ถ€ํŠธ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐฑ์—”๋“œ๋ฅผ ์—ฐ๋™ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

react๋ฅผ ์“ฐ๋‹ˆ ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ๋„ ์ž˜ ๋ชจ๋ฅด๊ฒ ๊ณ , ajax ํ˜ธ์ถœ์„ jquery๋กœ๋งŒ ํ–ˆ์—ˆ๋Š”๋ฐ fetch ๋ฉ”์„œ๋“œ๋ฅผ ์“ฐ๋Š” ๊ฒƒ์ด ๊ณต์‹๋ฌธ์„œ์˜ ์˜ˆ์ œ๋กœ ๋‚˜์™€์žˆ์–ด์„œ ๊ทธ๊ฑธ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. 

๋ฐฑ์—”๋“œ์— CORS ์„ค์ •๋„ ๋นผ๋จน์—ˆ์—ˆ๊ณ ์š”...

์ผ๋‹จ ํ™”๋ฉด์—์„œ ๋ฐ”๋€ ์ ์€ Blog > ๋‹ค์ด์–ด๋ฆฌ ๋ฉ”๋‰ด๋ฅผ ์„ ํƒํ•˜๋ฉด ๊ฒ€์ƒ‰์„ ์œ„ํ•œ ์ž…๋ ฅ์ฐฝ๊ณผ ๋ฒ„ํŠผ, ์ƒˆ๊ธ€ ๋“ฑ๋ก์„ ์œ„ํ•œ ๋ฒ„ํŠผ์„ ๋„ฃ์—ˆ๊ณ (๊ธฐ๋Šฅ์€ ์•„์ง ๊ตฌํ˜„๋ชปํ–ˆ๋„ค์š”), ๋ฆฌ์ŠคํŠธ ๋ชฉ๋ก ์กฐํšŒํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ๊ฐ„๋‹จํ•˜๊ฒŒ ์—ฐ๊ฒฐํ•ด๋†“์•˜์Šต๋‹ˆ๋‹ค. ์†Œ์Šค์ฝ”๋“œ๋Š” ๋งŽ์ด ์ˆ˜์ •ํ–ˆ๋Š”๋ฐ ์‹ค์ œ ํ™”๋ฉด์—์„œ ๋ฐ”๋€๊ฑด ๋ญ ์—†๋„ค์š” ใ…กใ…กใ…‹

 

๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

 

์•ž์œผ๋กœ ํ•  ์ผ๋“ค์„ ๋‚˜์—ดํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

  • ๋“ฑ๋ก๊ธฐ๋Šฅ ํ”„๋ก ํŠธ ๊ตฌํ˜„ ๋ฐ ๋ฐฑ์—”๋“œ์™€ ์—ฐ๋™
  • ๊ฒ€์ƒ‰๊ธฐ๋Šฅ ๋ฐฑ์—”๋“œ ๊ตฌํ˜„ ๋ฐ ํ”„๋ก ํŠธ์™€ ์—ฐ๋™
  • ๋ชฉ๋ก์˜ ํ—ค๋”์— ์ œ๋ชฉ, ๋‚ด์šฉ, ์ˆ˜์ •์ผ ํ‘œ์‹œ
  • ๋‚ด์šฉ์€ ํ•œ ์ค„์„ ๋„˜๊ธฐ์ง€ ์•Š๋„๋ก ์ผ๋ถ€๋งŒ ์ถœ๋ ฅ๋˜๋„๋ก ์ˆ˜์ •
  • ๋“ฑ๋ก์ผ์‹œ ํ‘œ์‹œ -> ๋ฐฑ์—”๋“œ ์ˆ˜์ •
  • ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ˆ˜์ •์ผ์‹œ๋„ ๊ด€๋ฆฌ
  • ๊ฒŒ์‹œ๊ธ€ ์ขŒ์ธก์— ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ ๋„ฃ๊ธฐ -> ๋ชฝ๊ณ DB์— auto increment ๊ธฐ๋Šฅ์ด ์—†์–ด ์†Œ์Šค๋ ˆ๋ฒจ์—์„œ ๊ตฌํ˜„ํ•ด์•ผํ•จ

์—ญ์‹œ ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ํ˜ผ์ž ํ•˜๋ ค๋‹ˆ ํ•  ์ผ์ด ๋„ˆ๋ฌด ๋งŽ๋„ค์š” ใ…œใ…œ

๊ทธ๋ž˜๋„ ์žฌ๋ฏธ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด ๊ฐ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์ƒˆ ํ‹ฐ์Šคํ† ๋ฆฌ๊ฐ€ ์ž์ฒด๊ด‘๊ณ ๋ฅผ ๋ถ™์—ฌ์„œ ๊ด‘๊ณ ๊ฐ€ ์ž๊พธ ๋œจ๋Š”๊ฒƒ ๊ฐ™๋„ค์š”...๋กœ๊ทธ์ธํ•  ๋•Œ๋„ ๋œจ๊ณ ...

๋นจ๋ฆฌ ๋ธ”๋กœ๊ทธ ์•ฑ ๋งŒ๋“ค์–ด์„œ ๋ผ์ด๋ธŒํ•ด์„œ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์‹ถ๋„ค์š”

 

 

์ฐธ๊ณ ๋ฌธ์„œ:

์Šคํ”„๋ง๋ถ€ํŠธ CORS ์„ค์ •ํ•˜๊ธฐ >> spring.io/guides/gs/rest-service-cors/#global-cors-configuration

 

Enabling Cross Origin Requests for a RESTful Web Service

this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team

spring.io

๋ฆฌ์•กํŠธ ajax ํ˜ธ์ถœํ•˜๊ธฐ >> reactjs.org/docs/faq-ajax.html

 

AJAX and APIs – React

A JavaScript library for building user interfaces

reactjs.org

๋ฆฌ์•กํŠธ ๋ถ€๋ชจ์ƒํƒœ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ >> stackoverflow.com/questions/35537229/how-to-update-parents-state-in-react

 

How to update parent's state in React?

My structure looks as follows: Component 1 - |- Component 2 - - |- Component 4 - - - |- Component 5 Component 3 Component 3 should display some data depending on state of Component 5....

stackoverflow.com

 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Java + SpringBoot + Mongo DB ๋กœ ๊ตฌํ˜„ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๊ฐ๊ฐ ์‚ฌ์šฉํ•  ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

- Java 8 (์˜ค๋ผํดjdk๊ฐ€ ์ƒ์šฉ๋ชฉ์ ์œผ๋กœ๋Š” ์œ ๋ฃŒํ™”๋˜์–ด ์ถ”ํ›„ ์ฝ”ํ‹€๋ฆฐ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ด์•ผ๊ฒ ๋„ค์š”)

- Springboot 2.4.0 (20๋…„ 11์›” ํ˜„์žฌ ์ตœ์‹ ๋ฒ„์ „)

- Mongo DB 4.4.2 Community Server (20๋…„ 11์›” ํ˜„์žฌ ์ตœ์‹ ๋ฒ„์ „)

 

๋ชฝ๊ณ ๋””๋น„ ์„ค์น˜ ๊ด€๋ จํ•ด์„œ๋Š” ๋ชฝ๊ณ DB ์ตœ์‹ ๋ฒ„์ „ ์„ค์น˜ํ•˜๊ธฐ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์„ค์น˜ ํ›„ ์‚ฌ์šฉ์ž ๊ณ„์ • ์ƒ์„ฑ ๋ฐ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ƒ์„ฑ ๊ด€๋ จํ•ด์„œ๋Š” [๋ชฝ๊ณ DB] ๊ธฐ๋ณธ๋ช…๋ น์–ด ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

 

์ด์ œ ๊ทธ๋ž˜๋“ค ์ž๋ฐ” ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜์—ฌ Blog > ๋‹ค์ด์–ด๋ฆฌ ๋ฉ”๋‰ด์—์„œ ์‚ฌ์šฉํ•  CRUD๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋จผ์ € ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ธ”๋กœ๊ทธ ๋งŒ๋“ค๊ธฐ ๋ฐฑ์—”๋“œ ํ”„๋กœ์ ํŠธ

 

์šฐ์„  build.graldeํŒŒ์ผ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

plugins {
    id "org.springframework.boot" version "2.4.0"
    id 'java'
}

group 'com.keichee'
version '1.0-SNAPSHOT'
sourceCompatibility = "1.8"

repositories {
    jcenter()
}

ext {
    springVersion = '2.4.0'
}

dependencies {
    testImplementation group: 'junit', name: 'junit', version: '4.12'

    implementation 'org.mongodb:mongodb-driver-sync:4.1.1'
    testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'

    implementation "org.springframework.boot:spring-boot-starter-web:$springVersion"
    testImplementation("org.springframework.boot:spring-boot-starter-test:$springVersion") {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }

    compileOnly 'org.projectlombok:lombok:1.18.16'
    annotationProcessor 'org.projectlombok:lombok:1.18.16'

    testCompileOnly 'org.projectlombok:lombok:1.18.16'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'

    implementation "io.springfox:springfox-boot-starter:3.0.0"
    implementation 'io.springfox:springfox-swagger-ui:3.0.0'

    implementation 'com.google.guava:guava:30.0-jre'
}

test {
    useJUnitPlatform()
}

 

mongodb-driver ๋Š” sync 4.1.1 ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋กœ๊น…์„ ์œ„ํ•ด์„œ logback-classic์„ ์ถ”๊ฐ€ํ–ˆ๊ณ  

api ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก spring-boot-starter-web์„ ์ถ”๊ฐ€

getter, setter ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ์„ ์œ„ํ•ด lombok ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๊ณ 

์Šค์›จ๊ฑฐ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  springfox ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค๋„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ œ ๋ชฝ๊ณ DB์™€ ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ์„ค์ •์„ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด์ค๋‹ˆ๋‹ค.

@Configuration
public class MongoConfig {

    private static final String host = "localhost";
    private static final int port = 27017;
    private static final String database = "blogapp";

    @Bean
    public MongoDatabase blogAppDatabase() {
        MongoClient client = MongoClients.create(
                MongoClientSettings.builder()
                        .applyToClusterSettings(builder ->
                                builder.hosts(Collections.singletonList(new ServerAddress(host, port))))
                        .build());
        return client.getDatabase(database);
    }
}

 

์ปจํŠธ๋กค๋Ÿฌ์—๋Š” ๋”ฑ 4๊ฐœ์˜ Restful API๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

@Slf4j
@RestController
@RequestMapping("/diary/life")
@AllArgsConstructor
public class DiaryLifeController {

    private final DiaryLifeService diaryLifeService;

    @ApiOperation("์ „์ฒด ๋ชฉ๋ก ์กฐํšŒ")
    @GetMapping
    public Response<List<Post>> getPosts() {
        log.info("์ „์ฒด ๋ชฉ๋ก ์กฐํšŒ");

        return new Response<>(diaryLifeService.getPosts(null));
    }

    @ApiOperation("๋‹ค์ด์–ด๋ฆฌ ํฌ์ŠคํŒ… ์‹ ๊ทœ์ƒ์„ฑ")
    @PostMapping
    public Response<Void> savePost(@RequestBody Post post) {
        validatePostInput(post);
        diaryLifeService.createPost(post);
        return new Response<>();
    }

    @ApiOperation("๋‹ค์ด์–ด๋ฆฌ ํฌ์ŠคํŒ… ์—…๋ฐ์ดํŠธ")
    @PutMapping
    public Response<Void> updatePost(@RequestBody Post post) {
        validatePostInput(post);
        diaryLifeService.updatePost(post);
        return new Response<>();
    }

    @ApiOperation("๋‹ค์ด์–ด๋ฆฌ ํฌ์ŠคํŒ… ์‚ญ์ œ")
    @DeleteMapping
    public Response<Void> deletePost(@RequestParam String _id) {
        diaryLifeService.deletePost(_id);
        return new Response<>();
    }

    private void validatePostInput(Post post) {
        if (ObjectUtils.isEmpty(post.getTitle())) {
            throw new BadRequestException("No TITLE exists.");
        }
        if (ObjectUtils.isEmpty(post.getContent())) {
            throw new BadRequestException("No CONTENT exists.");
        }
    }

    @ExceptionHandler
    public ResponseEntity<Response<String>> badRequest(BadRequestException e) {
        log.error("Bad request.., e-msg:{}", e.getMessage(), e);
        return ResponseEntity.badRequest().body(new Response<>(e.getMessage()));
    }
}

 

์Šค์›จ๊ฑฐ๋กœ ๋ณด๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์ด์–ด๋ฆฌ API ์Šค์›จ๊ฑฐ

 

์Šค์›จ๊ฑฐ๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ•œ๋ฒˆ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

ํ˜„์žฌ ๊ตฌํ˜„๋œ ๊ธฐ๋Šฅ์€ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ ๊นŒ์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€ ์ž‘์—…ํ•˜๋ฉด์„œ ์‰ฝ๊ฒŒ ํ’€๋ฆฌ์ง€ ์•Š์•˜๋˜ ๋ถ€๋ถ„์€ ๋ชฝ๊ณ DB๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋‹ˆ ๋ชฝ๊ณ DB ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ด์šฉํ•œ CRUD๋งŒ๋“œ๋Š” ๋ถ€๋ถ„์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด RDS์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ObjectID ๋กœ ํ•ธ๋“ค๋ง์„ ํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์—ˆ๊ณ , auto increment pk ์„ค์ •์„ ๋”ฐ๋กœ ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ฒŒ์‹œ๊ธ€์˜ ๋ฒˆํ˜ธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์•ผํ• ์ง€ ๊ณ ๋ฏผ์ด ์ข€ ๋˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๊ฐ ๊ฒŒ์‹œ๊ธ€๋งˆ๋‹ค ์‹œํ€€์Šค๊ฐ’์„ ๋„ฃ์–ด์ค˜์•ผํ•˜๋Š”๋ฐ ๊ตฌ๊ธ€๋งํ•ด์„œ ๋‚˜์˜ค๋Š” ๊ฒƒ๋“ค์€ synchronized ๊ฐ€ ์•ˆ๋  ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์—ฌ์„œ ํ…Œ์ŠคํŠธ๋„ ์ข€ ํ•ด๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€ ๋ฐฑ์—”๋“œ์˜ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ˜„์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ์˜ฌ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„  ํ™”๋ฉด ๊ธฐํš๋ถ€ํ„ฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

ํ‡ด๊ทผ ๊ธธ ์ง€ํ•˜์ฒ ์—์„œ ํ•œ์‹œ๊ฐ„ ๋™์•ˆ ๊ฐค๋…ธํŠธ์—๋‹ค๊ฐ€ ๋„์ ์—ฌ๋ดค๋‹ค.

์›Œ๋‚™ ๊ผผ๊ผผํ•œ ์Šคํƒ€์ผ์ด๋ผ ์ด๊ฒƒ์ €๊ฒƒ ๋””ํ…Œ์ผํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๋‹ค ์ ์–ด๋„ฃ๊ณ  ์‹ถ์—ˆ์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ์‹œ์ž‘ํ•˜๋ฉด ํž˜๋“ค์–ด์„œ ์ค‘๋„ํฌ๊ธฐํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™์•„ ๊ณ„์† ๋“œ๋Š” ์ƒ๊ฐ๋“ค์„ ๋ฟŒ๋ฆฌ์น˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ๋งŒ ๋„์ ์˜€๋‹ค.

๊ฐค๋Ÿญ์‹œ๋…ธํŠธ์˜ SํŽœ์„ ์ด์šฉํ•œ ๋ฉ”๋ชจ๊ฐ€ ์ฒ˜์Œ์ธ์ง€๋ผ ์„œํˆฌ๋ฅด๊ฒŒ ์ž‘์„ฑํ–ˆ๋‹ค ใ…Ž

๋ฉ”์ธํ™”๋ฉด์€ ํฌ๊ฒŒ ์ƒ๋‹จ๋ถ€(ํ—ค๋”๋ถ€๋ถ„๊ณผ ์ตœ์ƒ์œ„๋ฉ”๋‰ด)์™€ ํ•˜๋‹จ๋ถ€(์‚ฌ์ด๋“œ๋ฉ”๋‰ด + ์ปจํ…ํŠธ)๋กœ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

์ปจํ…ํŠธ ์˜์—ญ์€ ์ขŒ์ธก์— ์‚ฌ์ด๋“œ๋ฉ”๋‰ด๊ฐ€ ์žˆ์„์ˆ˜๋„ ์žˆ๊ณ  ์—†์„์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์นด๋“œํ˜• ๋ชฉ๋ก๋ณด๊ฐ€์™€ ๋ฆฌ์ŠคํŠธํ˜•์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ณ„ํš์ด๋‹ค.

์ตœ์ƒ์œ„ ๋ฉ”๋‰ด๋Š” ์ฃผ์ธ์žฅ ๋˜๋Š” ๋ธ”๋กœ๊ทธ์˜ ์†Œ๊ฐœ(Intro), ๋ธ”๋กœ๊ทธ(Blog), ๊ทธ๋ฆฌ๊ณ  ๋ถ„์„/ํ†ต๊ณ„(Stats) ๋กœ ๊ตฌ์„ฑํ–ˆ๋‹ค.
๋ธ”๋กœ๊ทธ๋ฉ”๋‰ด์˜ ํ•˜์œ„์—๋Š” ๊ฐœ๋ฐœ์ผ์ง€, ๋‹ค์ด์–ด๋ฆฌ, ์ œํ’ˆ๋ฆฌ๋ทฐ, ์—ฌํ–‰์ •๋ณด ๋ฉ”๋‰ด๊ฐ€์žˆ๊ณ , ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ถ„์„ํ†ต๊ณ„ ๋ฉ”๋‰ด์—๋Š” ๊ฐ์ข… ํ†ต๊ณ„์ž๋ฃŒ๋ฅผ ๊ณต์œ ํ•  ์ƒ๊ฐ์ด๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด๋ณธ ํ™”๋ฉด์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

์ด์ œ ๊ฐ ๋ฉ”๋‰ด๋ณ„ ํ™”๋ฉด ๊ธฐํš ๋ฐ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

์šฐ์„  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” AWS document DB์—์„œ ์ง€์›ํ•˜๋Š” mongo DB๋ฅผ ์จ๋ณผ ์˜ˆ์ •์ด๋‹ค.

ํ•œ row์— ๋Œ€ํ•ด์„œ ์ด 16MB ๊นŒ์ง€ ๋ฐ์ดํ„ฐ ์ €์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ˆ ์ด๋ฏธ์ง€๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•ด์„œ๋„ ํ•˜๋‚˜์˜ row์— ์ €์žฅ์„ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. 

๋ฌด๋ฃŒ๋กœ mongoDB ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด๋Ÿฐ์ €๋Ÿฐ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ์ œ์•ฝ์‚ฌํ•ญ์ด ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด๋‹ค.

๋ฐฑ์—”๋“œ๋Š”.....์—ญ์‹œ ์ œ์ผ ๋นจ๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํ”„๋ง๋ถ€ํŠธ๊ธฐ๋ฐ˜์˜ ์ž๋ฐ”๋กœ ๊ฐ€์•ผ๊ฒ ๋‹ค.. ์‹œ๊ฐ„๋‹จ์ถ•์„ ์œ„ํ•ด์„œ...

 

๋ธ”๋กœ๊ทธ ์›น์•ฑ ๋งŒ๋“ค๊ธฐ ๊ฐœ์ธํ”„๋กœ์ ํŠธ

ํ‹ฐ์Šคํ† ๋ฆฌ ๋ธ”๋กœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•œ์ง€๋„ ๋ช‡ ๋…„์ด ๋œ ๊ฒƒ ๊ฐ™๋‹ค.

์ฒ˜์Œ ์‹œ์ž‘์€ ๊ตฌ๊ธ€ ๊ด‘๊ณ ๋ฅผ ๋ถ™์—ฌ์„œ ๊ด‘๊ณ ์ˆ˜์ต์„ ์–ป์„ ์ƒ๊ฐ์œผ๋กœ ์‹œ์ž‘ํ–ˆ์—ˆ๋Š”๋ฐ

์ด์ง์„ ํ•˜๊ณ  ๋Œ€๊ทœ๋ชจ ์•ฑ์„ ๊ฑฐ์˜ ํ˜ผ์ž์„œ ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ์‹ ๊ทœ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ ๋„ˆ๋ฌด ๋ฐ”๋น ์„œ ๊ธ€์„ ์“ธ ์‹œ๊ฐ„์ด ์—†์—ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ 2๋…„์ด ๋„˜๋Š” ์‹œ๊ฐ„์ด ํ›Œ์ฉ ํ˜๋ €๋‹ค.

์ด์งํ•œ ํšŒ์‚ฌ์—์„œ ๊ด€๋ฆฌ์ž ์›น์•ฑ์„ ํ˜ผ์ž ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด์„œ ํ‰์†Œ ํ’€์Šคํƒ์ด ๋˜๊ณ ์‹ถ์—ˆ๋˜ ๊ฟˆ์ด ๋‹ค์‹œ ์‚ด์•„๋‚˜๊ธฐ ์‹œ์ž‘ํ–ˆ๊ณ 

๋ช‡ ์ผ ์ „๋ถ€ํ„ฐ ๋ฆฌ์•กํŠธ ๊ณต๋ถ€๋ฅผ ์‹œ์ž‘ํ–ˆ๋‹ค.

์ƒํ™œ์ฝ”๋”ฉ์˜ ๋ฆฌ์•กํŠธ ๋™์˜์ƒ๋„ ๋ณด๊ณ , ๋ฆฌ๋•์Šค ๊ฐ•์ขŒ๋„ ๋ณด๊ณ ...

ํ•˜์ง€๋งŒ ์—ญ์‹œ ๋ณด๊ธฐ๋งŒ ํ•˜๋Š”๊ฑด ํฐ ๋„์›€์ด ๋˜์ง€ ์•Š๊ธฐ์— ์ง์ ‘ ์ฝ”๋”ฉ์„ ํ•ด๊ฐ€๋ฉด์„œ ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๊ณ 

์–ด๋–ค ํ”„๋กœ์ ํŠธ๋ฅผ ํ•ด๋ณผ๊นŒ ํ•˜๋‹ค๊ฐ€ ๊ฐœ์ธ ๋ธ”๋กœ๊ทธ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

ํ‹ฐ์Šคํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ๋“ค๋ณด๋‹ค ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•„ ์ข‹๊ธดํ•˜์ง€๋งŒ ๊ทธ๋ž˜๋„ ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์„ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ‹ฐ์Šคํ† ๋ฆฌ๊ฐ€ ์„œ๋น„์Šค ์ค‘์ง€ ์„ ์–ธ์„ ํ•ด๋ฒ„๋ฆฌ๋ฉด? ใ… ใ… 

๊ทธ๋Ÿผ ์ž‘์„ฑํ•œ ๊ธ€๋“ค๋„ ๋ชจ๋‘ ์‚ฌ๋ผ์ง€๊ฒŒ ๋ ํ…Œ๋‹ˆ ๋ง์ด๋‹ค. 

์„ค๋ น ์ž‘์„ฑํ•œ ๊ธ€๋“ค์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๊ณ  ํ•ด๋„ ํฌ๋งท์„ ์–ด๋–ป๊ฒŒ ์ œ๊ณตํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ์— ์˜ฎ๊ฒจ์‹ฌ๊ธฐ๋„ ๋ถˆํŽธํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธฐํšŒ์— ๊ฐœ์ธ ๋ธ”๋กœ๊ทธ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ๋„๋ฉ”์ธ ์—ฐ๋™๋„ ํ•˜๊ณ  ๊พธ์ค€ํžˆ ์ž˜ ๊ฐ€๊พธ์–ด ๋‚˜๊ฐ€์•ผ ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์„ ํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ธ”๋กœ๊ทธ๋ฅผ ์™„์„ฑํ•˜๊ธฐ ๊นŒ์ง€์˜ ๊ณผ์ •์„ ์ด๊ณณ์— ๋‚จ๊ฒจ๋‘๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

๊ทธ๋ ‡๊ฒŒ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ๋ฆฌ์•กํŠธ๋กœ ๊ฐœ์ธ๋ธ”๋กœ๊ทธ ๋งŒ๋“ค๊ธฐ๋Š” ์‹œ์ž‘์ด ๋˜์—ˆ๋‹ค...

 

ํ•ด์•ผํ•  ์ผ์€ ๋งŽ๋‹ค. ์„œ๋ฒ„๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•  ๊ฒƒ์ด๋ฉฐ ์–ด๋–ค ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ธ์ง€ ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์€ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€ ๋“ฑ๋“ฑ...

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ๊ฒƒ๋“ค์„ ์ƒ์„ธํ•˜๊ฒŒ ๋‹ค ๋”ฐ์ ธ๊ฐ€๋ฉด์„œ ํ•˜๊ธฐ์—๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋‹ˆ ๋ฆฌ์•กํŠธ๋กœ ํ™”๋ฉด๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์— ์ผ๋‹จ ์ง‘์ค‘ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ ์‚ฌ์ดํŠธ๋ฅผ ๋Œ์•„๋‹ค๋‹ˆ๋ฉด์„œ ๋ฒค์น˜๋งˆํ‚นํ•˜๋ฉด์„œ ํ•ด์•ผ๊ฒ ๋‹ค

๋ฐฑ์—”๋“œ๋Š” ๋Š˜ ํ•ด์˜ค๋˜ ์ž๋ฐ”์™€ ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ์ด์šฉํ• ์ง€...์˜ˆ์ „์— ํ•ด๋ดค๋˜ ๋…ธ๋“œ๋ฅผ ๋‹ค์‹œ ์จ๋ณผ์ง€...ํŒŒ์ด์ฌ์„ ์จ๋ณผ์ง€ ๊ณ ๋ฏผ์ด ์ข€ ๋˜๋Š”๋ฐ...

์ž๋ฐ”+์Šคํ”„๋ง๋ถ€ํŠธ๋Š” ์—…์œผ๋กœ ํ•˜๊ณ ์žˆ๋Š” ์ŠคํŽ™์ด๋‹ค๋ณด๋‹ˆ ๋น ๋ฅธ ์‹œ๊ฐ„๋‚ด์— ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด ๋ฆฌ์•กํŠธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ๊ด€๋ฆฌํ•ด์•ผํ•  ๊ฒƒ ๊ฐ™๊ณ  ๋…ธ๋“œ์„œ๋ฒ„์™€ ์ž๋ฐ”์„œ๋ฒ„๋ฅผ ๋„์›Œ์•ผ ์™„์ „์ฒด๊ฐ€ ๋œ๋‹ค. 

๋…ธ๋“œ๋ฅผ ์“ฐ๋ฉด ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตณ์ด ๋ถ„๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  ์„œ๋ฒ„๋„ ๋…ธ๋“œ์„œ๋ฒ„๋งŒ ๋„์šฐ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ์ธ์šฉ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ์—๋Š” ๋” ํŽธํ•˜๊ธด ํ•˜์ง€๋งŒ, ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ฅผ ์“ฐ์ž๋‹ˆ ์ข€ ๋ถ€๋‹ด์ด ๋˜๊ธดํ•œ๋‹ค.

 

์ผ๋‹จ์€ ๋ฆฌ์•กํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๊ป๋ฐ๊ธฐ(ํ”„๋ก ํŠธ)๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด๋†“๊ณ  ๊ณ ๋ฏผํ•ด์•ผ๊ฒ ๋‹ค.