Kotlin & Java/프로젝트

[Code Execution API] 1. 프로그래밍 코드 실행 API 만들어보기

상쾌한기분 2023. 3. 22. 19:33
반응형

1. 프로그래밍 코드 실행 API 만들어보기

구글에서 online python 등을 검색하거나 코딩 테스트 등 웹에서 코드를 실행 가능한 서비스를 제공해 주는 웹 페이지들이 있는데 한번 궁금해서 구현을 해보았다.

2. 개발 스펙 선택과 제공할 언어 선택

개발 진행을 위해서는 우선 API 개발 언어와 프레임워크 등과 기능 제공할 언어와 정해야 하는데 하기처럼 정해서 진행했다.

API 개발

  • Java 17 (correto)
  • Spring boot 3.0.2
  • JPA Hibernate 6.1.6

제공할 언어

  • Python 3.8
  • Python 2.7
  • Php 8.2
  • Php 7.4
  • Gcc 4.9
  • Java (예정)
  • Go (예정)

3.  최종 개발 화면

우선 개발한 내용부터 먼저 살펴보자면 하기 캡쳐 화면처럼 기능을 제공해준다.

OpenAPI Swagger 

Test view with Javascript 

4. 스프링 부트 설정 파일

우선 신규 스프링 부트 신규 프로젝트를 생성하고 하기처럼 설정을 진행

application-local.yml

spring:
  servlet:
    multipart:
      max-file-size: 10MB

  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:mysql://localhost:33061/IDE
    username: root
    password: rootroot
    driver-class-name: com.mysql.cj.jdbc.Driver
    dbcp2:
      validation-query: SELECT 1
    hikari:
      maximum-pool-size: 10
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQLDialect
    open-in-view: false
    hibernate:
      ddl-auto: update
    properties:
      use_sql_comments: true
      hibernate:
        default_batch_fetch_size: 1000
        show_sql: false
        format_sql: false
        globally_quoted_identifiers: true

  jackson:
    serialization:
      indent_output: true

logging:
  level:
    p6spy: info
    web: info
    root: info
    org:
      springframework:
        web: info
      hibernate:
        sql: info
        type: info
        descriptor:
          sql: info
        orm:
          jdbc:
            bind: info

springdoc:
  api-docs:
    enabled: true
  swagger-ui:
    enabled: true
    display-request-duration: true
    tags-sorter: alpha
    operations-sorter: alpha
#  paths-to-match: /*
#  packages-to-scan: *

server:
  port: 9000

jwt_secret: 359ad650b2a631ab4195e2540afa310cd59010b1 # openssl rand -hex 20

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.2'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'org.hibernate.orm' version '6.1.6.Final'
    id 'org.graalvm.buildtools.native' version '0.9.18'
    id 'org.asciidoctor.convert' version '1.5.8'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

ext {
    set('snippetsDir', file("build/generated-snippets"))
//    set('springShellVersion', "3.0.0")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-hateoas'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
//    implementation 'org.springframework.shell:spring-shell-starter'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
    testImplementation 'org.springframework.security:spring-security-test'

    // p6spy
    implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'

    // https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all
    testImplementation 'org.hamcrest:hamcrest-all:1.3' // assertThat

    // rest template
    implementation 'org.apache.httpcomponents.core5:httpcore5:5.2.1'
    implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'

    // hibernate Json Field Helper
    implementation 'io.hypersistence:hypersistence-utils-hibernate-60:3.1.2'
    implementation 'com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations'

    // MapStruct
    annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
    testAnnotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"

    // JWT
    implementation 'com.auth0:java-jwt:4.2.1'

    // https://springdoc.org/v2/#spring-security-support
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.0.2'
    implementation 'org.springdoc:springdoc-openapi-starter-common:2.0.2'
    implementation 'org.springdoc:springdoc-openapi-security:1.6.14'
//    implementation 'org.springdoc:springdoc-openapi-data-rest:1.6.14'

    // docker client : https://github.com/docker-java/docker-java  /  https://www.baeldung.com/docker-java-api
    // https://github.com/docker-java/docker-java/blob/master/docs/getting_started.md
    implementation 'com.github.docker-java:docker-java:3.2.7'
    implementation 'com.github.docker-java:docker-java-api:3.2.7'
    implementation 'com.github.docker-java:docker-java-core:3.2.7'
    implementation 'com.github.docker-java:docker-java-transport-httpclient5:3.2.7'

    // docker client dependency
//    implementation 'javax.ws.rs:javax.ws.rs:1.0'
    implementation 'javax.ws.rs:javax.ws.rs-api:2.1.1'
    implementation 'org.glassfish.jersey.core:jersey-common:2.34'
    implementation 'org.glassfish.jersey.core:jersey-client:2.34'
    implementation 'org.glassfish.jersey.core:jersey-server:2.34'
    compileOnly 'javax:javaee-api:8.0'
    implementation 'javax.inject:javax.inject:1'
    implementation 'net.java.dev.jna:jna:5.8.0'
}

//dependencyManagement {
//    imports {
//        mavenBom "org.springframework.shell:spring-shell-dependencies:${springShellVersion}"
//    }
//}

tasks.named('test') {
    outputs.dir snippetsDir
    useJUnitPlatform()
}

tasks.named('asciidoctor') {
    inputs.dir snippetsDir
    dependsOn test
}

hibernate {
    enhancement {
        lazyInitialization true
        dirtyTracking true
        associationManagement true
    }
}
728x90
반응형