-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #93 from boostcampwm-2024/feature/api/stockList-#57
[BE] 5.03 주식 리스트 가져오기 API 구현
- Loading branch information
Showing
9 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class StockListResponseDto { | ||
@ApiProperty({ example: '005930', description: '종목 코드' }) | ||
code: string; | ||
|
||
@ApiProperty({ example: '삼성전자', description: '종목 이름' }) | ||
name: string; | ||
|
||
@ApiProperty({ example: 'KOSPI', description: '시장' }) | ||
market: string; | ||
|
||
constructor(code: string, name: string, market: string) { | ||
this.code = code; | ||
this.name = name; | ||
this.market = market; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export interface SearchParams { | ||
name?: string; | ||
market?: string; | ||
code?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { Controller, Get, Query } from '@nestjs/common'; | ||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; | ||
import { StockListService } from './stock-list.service'; | ||
import { StockListResponseDto } from './dto/stock-list-response.dto'; | ||
|
||
@ApiTags('주식 리스트 API') | ||
@Controller('/api/stocks/list') | ||
export class StockListController { | ||
constructor(private readonly stockListService: StockListService) {} | ||
|
||
@ApiOperation({ | ||
summary: '전체 주식 종목 조회 API', | ||
description: '모든 주식 종목 리스트를 조회한다.', | ||
}) | ||
@Get() | ||
async findAll(): Promise<StockListResponseDto[]> { | ||
return this.stockListService.findAll(); | ||
} | ||
|
||
@ApiOperation({ | ||
summary: '주식 목록 검색 API', | ||
description: | ||
'주식 종목을 검색한다. name, market, code로 검색을 진행할 수 있다.', | ||
}) | ||
@ApiResponse({ | ||
status: 200, | ||
description: '주식 검색 성공', | ||
type: StockListResponseDto, | ||
isArray: true, | ||
}) | ||
@Get('/search') | ||
async searchWithQuery( | ||
@Query('name') name?: string, | ||
@Query('market') market?: string, | ||
@Query('code') code?: string, | ||
): Promise<StockListResponseDto[]> { | ||
return this.stockListService.search({ name, market, code }); | ||
} | ||
|
||
@ApiOperation({ | ||
summary: '특정 주식 종목 조회 API', | ||
description: 'code를 이용해 특정 주식 정보를 조회한다.', | ||
}) | ||
@ApiResponse({ | ||
status: 200, | ||
description: 'code를 이용한 주식 조회 성공', | ||
type: StockListResponseDto, | ||
}) | ||
@Get('/:code') | ||
async findOne(@Query('code') code: string): Promise<StockListResponseDto> { | ||
return this.stockListService.findOne(code); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm'; | ||
|
||
@Entity() | ||
export class Stocks extends BaseEntity { | ||
@PrimaryColumn() | ||
code: string; | ||
|
||
@Column() | ||
name: string; | ||
|
||
@Column() | ||
market: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { TypeOrmModule } from '@nestjs/typeorm'; | ||
import { StockListRepository } from './stock-list.repostiory'; | ||
import { StockListService } from './stock-list.service'; | ||
import { StockListController } from './stock-list.controller'; | ||
import { Stocks } from './stock-list.entity'; | ||
|
||
@Module({ | ||
imports: [TypeOrmModule.forFeature([Stocks])], | ||
controllers: [StockListController], | ||
providers: [StockListRepository, StockListService], | ||
exports: [], | ||
}) | ||
export class StockListModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { InjectDataSource } from '@nestjs/typeorm'; | ||
import { DataSource, Repository } from 'typeorm'; | ||
import { Stocks } from './stock-list.entity'; | ||
import { SearchParams } from './interface/search-params.interface'; | ||
|
||
@Injectable() | ||
export class StockListRepository extends Repository<Stocks> { | ||
constructor(@InjectDataSource() dataSource: DataSource) { | ||
super(Stocks, dataSource.createEntityManager()); | ||
} | ||
|
||
async findAllStocks() { | ||
return this.find(); | ||
} | ||
|
||
async findOneStock(code: string): Promise<Stocks> { | ||
return this.findOne({ where: { code } }); | ||
} | ||
|
||
async search(params: SearchParams): Promise<Stocks[]> { | ||
const queryBuilder = this.createQueryBuilder(); | ||
if (params.name) { | ||
queryBuilder.where('name LIKE :name', { name: `%${params.name}%` }); | ||
} | ||
if (params.market) { | ||
queryBuilder.andWhere('market LIKE :market', { | ||
market: `%${params.market}%`, | ||
}); | ||
} | ||
if (params.code) { | ||
queryBuilder.andWhere('code LIKE :code', { code: `%${params.code}%` }); | ||
} | ||
return queryBuilder.getMany(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Injectable, NotFoundException } from '@nestjs/common'; | ||
import { StockListRepository } from './stock-list.repostiory'; | ||
import { Stocks } from './stock-list.entity'; | ||
import { StockListResponseDto } from './dto/stock-list-response.dto'; | ||
import { SearchParams } from './interface/search-params.interface'; | ||
|
||
@Injectable() | ||
export class StockListService { | ||
constructor(private readonly stockListRepository: StockListRepository) {} | ||
|
||
private toResponseDto(stock: Stocks): StockListResponseDto { | ||
return new StockListResponseDto(stock.code, stock.name, stock.market); | ||
} | ||
|
||
async findAll() { | ||
const stocks = await this.stockListRepository.findAllStocks(); | ||
return stocks.map((stock) => this.toResponseDto(stock)); | ||
} | ||
|
||
async findOne(code: string) { | ||
const stock = await this.stockListRepository.findOneStock(code); | ||
|
||
if (!stock) { | ||
throw new NotFoundException(`Stock with code ${code} not found`); | ||
} | ||
return this.toResponseDto(stock); | ||
} | ||
|
||
async search(params: SearchParams): Promise<StockListResponseDto[]> { | ||
const stocks = await this.stockListRepository.search(params); | ||
return stocks.map((stock) => this.toResponseDto(stock)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import FinanceDataReader as fdr | ||
import json | ||
import os | ||
import mysql.connector | ||
from dotenv import load_dotenv | ||
from pathlib import Path | ||
|
||
root_dir = Path(__file__).parent | ||
env_path = os.path.join(root_dir, '.env') | ||
# .env 파일 로드 | ||
load_dotenv(env_path) | ||
|
||
db_config = { | ||
'host' : os.getenv('DB_HOST'), | ||
'user' : os.getenv('DB_USERNAME'), | ||
'password' : os.getenv('DB_PASSWD'), | ||
'database' : os.getenv('DB_DATABASE'), | ||
} | ||
|
||
def insert_stocks(stockData) : | ||
try : | ||
conn = mysql.connector.connect(**db_config) | ||
cursor = conn.cursor() | ||
|
||
insert_query = """INSERT INTO stocks (code, name, market) VALUES (%s, %s, %s) | ||
ON DUPLICATE KEY UPDATE name = VALUES(name), market = VALUES(market)""" | ||
|
||
records = stockData.to_dict('records') | ||
for record in records: | ||
values = (record['Code'], record['Name'], record['Market']) | ||
cursor.execute(insert_query, values) | ||
conn.commit() | ||
|
||
except Exception as e : | ||
print(e) | ||
conn.rollback() | ||
|
||
finally : | ||
if conn.is_connected() : | ||
cursor.close() | ||
conn.close() | ||
|
||
df_krx = fdr.StockListing('KRX') | ||
df_selected = df_krx[['Code','Name','Market']] | ||
|
||
insert_stocks(df_selected) |