I am writing an app with a post function.
The post contents will be stored in these paths:
const val PROFILE_PICTURE_PATH = "build/resources/main/static/profile_pictures/"
const val BANNER_IMAGE_PATH = "build/resources/main/static/banner_images/"
const val POST_CONTENT_PATH = "build/resources/main/static/post_contents/"
And Route.kt file with this
static {
resources("static")
}
When I run the server in localhost, I can get the content. However, when I deploy the backend to the server, I can not get images.
Related
I uploaded image and store it in specific folder, and it's working, but I want the images back as image_url, there is no way found in Ktor Web API.
Please help me if anyone has a solution.
Thanks.
To solve your problem you can serve static files:
embeddedServer(Netty, port = 9999, host = "localhost") {
routing {
static("folder_name") { // web path
files("folder_name") // folder from where to serve files
}
}
}.start(wait = true)
Also, you can have a specific route to respond with the contents of a specific image:
routing {
get("/folder_name/image.jpg") {
call.respondFile(File("./folder_name/image.jpg"))
}
}
please i need help with connecting a mongodb to my ktor application.
This is the code i have, as followed from this article: https://himanshoe.com/mongodb-in-ktor
class MongoDataHandler {
val client = KMongo.createClient().coroutine
val database = client.getDatabase("dev")
val userCollection = database.getCollection<User>()
suspend fun adduser(email: String, username: String, password: String): User? {
userCollection.insertOne(User(userId = null, email = email, userName = username, passwordHash = password))
return userCollection.findOne(User::email eq email )
}
suspend fun finduser(id: String): User?{
return userCollection.findOneById(id)
}
}
I installed mongodb as directed from their website. The mongodb is started as a service upon successful install. I run this command "C:\Program Files\MongoDB\Server\5.0\bin\mongo.exe" to use the mongodb. When i check for the available database using "show dbs", i realize that my database(dev) is not listed.
This is the dependency am using:
implementation("org.litote.kmongo:kmongo-coroutine:4.2.8")
And this the the error i am getting:
[eventLoopGroupProxy-4-1] INFO Application - 500 Internal Server Error:
POST - /user
I guess i am doing something wrong... thanks in advance
Try to change your MongoDataHandler to the following, using the MongoClients.create() method, and adding a codecRegistry to your client.
You will not need the connection string settings if you are using the local connection with the default settings:
class MongoDataHandler {
private val database: MongoDatabase
private val usersCollection: MongoCollection<User>
init {
val pojoCodecRegistry: CodecRegistry = fromProviders(
PojoCodecProvider.builder()
.automatic(true)
.build()
)
val codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry)
val settings: MongoClientSettings = MongoClientSettings.builder()
// .applyConnectionString("localhost") => add the connection string if not using localhost
.codecRegistry(codecRegistry)
.build()
val mongoClient = MongoClients.create(settings)
database = mongoClient.getDatabase("dev")
usersCollection = database.getCollection(User::class.java.name, User::class.java)
}
Also, if you are not using docker, try to use docker-compose to orchestrate your mongodb container:
version: '3'
services:
mongo:
image: mongo:latest
ports:
- "27017:27017"
If you want a running example with Ktor/MongoDB take a look in this project
I assume you are in development mode and trying this in our local machine.
Make sure you have MongoDB installed on the local machine and the local server is running well. Here is a guide for ubuntu.
After successful setup and installation of MongoDB, run this command
mongo --eval 'db.runCommand({ connectionStatus: 1 })'
The output should contain a line as below:
connecting to : mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Make sure to add this line while creating client in the ConnectionString like:\
private val client = KMongo.createClient(
ConnectionString("mongodb://127.0.0.1:27017")
).coroutine
Then try working on your requests/operations with the Ktor, it should work fine.
I'm building a microservice with the http4k framework using their Contract APIs. I can easily expose the swagger API description JSON on eg. /swagger.json with
fun app(): HttpHandler = "/" bind contract {
renderer = OpenApi3(ApiInfo("GoOut Locations API", "1.0"), Jackson)
descriptionPath = "/swagger.json"
routes += ...
}
Is there an easy way to expose the swagger UI so that 1) I can specify the path it will be available on. (eg. /swagger-ui) 2) The UI will be preconfigured to fetch the description JSON from the descriptionPath specified above.
An ideal API would look something like
fun app(): HttpHandler = "/" bind contract {
renderer = OpenApi3(ApiInfo("GoOut Locations API", "1.0"), Jackson)
descriptionPath = "/swagger.json"
uiPath = "/swagger-ui"
routes += ...
}
After a bit of searching I achieved this with combination of Web Jars and http4k's static routing.
The potential viewer of the docs must simply visit /docs path where he gets redirected to /docs/index.html?url=<path to Api description> where
index.html is a static Swagger UI entrypoint served from a web jar.
url query param tells the swagger UI where to fetch the OpenApi description from.
From the DX perspective we have a simple http4k application:
// path the OpenApi description will be exposed on
private const val API_DESCRIPTION_PATH = "/swagger.json"
fun app(): HttpHandler {
val api = contract {
renderer = OpenApi3(ApiInfo("Your API summary", "1.0"), Jackson)
descriptionPath = API_DESCRIPTION_PATH
// the actual API routes
routes += ...
}
return routes(
// the docs routes are not considered part of the API so we define them outside of the contract
swaggerUi(API_DESCRIPTION_PATH),
api
)
}
The swaggerUi handler implementation follows
/**
* Exposes Swagger UI with /docs path as its entry point.
* #param descriptionPath absolute path to API description JSON. The UI will be configured to fetch it after load.
*/
fun swaggerUi(descriptionPath: String): RoutingHttpHandler = routes(
"docs" bind Method.GET to {
Response(Status.FOUND).header("Location", "/docs/index.html?url=$descriptionPath")
},
// For some reason the static handler does not work without "/" path prefix.
"/docs" bind static(Classpath("META-INF/resources/webjars/swagger-ui/3.25.2"))
)
We also have to include the swagger-ui webjar as our dependency. Here's a Gradle directive:
implementation 'org.webjars:swagger-ui:3.25.2'
See the webjars website for Maven (and more) directives.
Note that the swaggerUi handler assumes its bound to the / root path of the whole service. However, that can be easily fixed.
As of http4k 4.28.1.0, there is now a way to do this. See the following code taken from this documentation page:
package guide.howto.create_a_swagger_ui
import org.http4k.contract.contract
import org.http4k.contract.meta
import org.http4k.contract.openapi.ApiInfo
import org.http4k.contract.openapi.v3.OpenApi3
import org.http4k.contract.ui.swaggerUi
import org.http4k.core.Body
import org.http4k.core.ContentType
import org.http4k.core.Method.GET
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.core.Uri
import org.http4k.core.with
import org.http4k.lens.string
import org.http4k.routing.routes
import org.http4k.server.SunHttp
import org.http4k.server.asServer
fun main() {
val greetingLens = Body.string(ContentType.TEXT_PLAIN).toLens()
// Define a single http route for our contract
val helloHandler = "/v1/hello" meta {
operationId = "v1Hello"
summary = "Say Hello"
returning(OK, greetingLens to "Sample Greeting")
} bindContract GET to { _: Request ->
Response(OK).with(greetingLens of "HI!")
}
// Define a contract, and render an OpenApi 3 spec at "/spec"
val v1Api = contract {
routes += helloHandler
renderer = OpenApi3(
ApiInfo("Hello Server - Developer UI", "99.3.4")
)
descriptionPath = "spec"
}
// Build a Swagger UI based on the OpenApi spec defined at "/spec"
val ui = swaggerUi(
Uri.of("spec"),
title = "Hello Server",
displayOperationId = true
)
// Combine our api, spec, and ui; then start a server
// The Swagger UI is available on the root "/" path
routes(v1Api, ui)
.asServer(SunHttp(8080))
.start()
.block()
}
The solution using the webjar does not work anymore for SwaggerUI version >= 4.1.3 as the url parameter is ignored (see this issue / the release notes). The URL has to be either specified in the HTML or the url parameter needs to be enabled in the HTML.
So for now the solution seems to be to unpack the UI, update index.html, and serve directly rather through the webjar.
http4k doesn't ship with a version of the OpenApi UI. You can easily ship a version of the UI though by:
unpacking the OpenApi UI into the src/main/resources/public folder
Using a static routing block to server the resources. There is an example of that here: https://github.com/http4k/http4k-by-example/blob/22dcc9a83c497253c29830d5bc981afa5fbbe4ff/src/main/kotlin/verysecuresystems/SecuritySystem.kt#L61
I develop a project with nuxt js. And I get problem like this below.
I get result from restful api of backend with asynchronous ajax
request.
I need add the result as a header to every quest with the
ajax library of axios.
So I save the result on browser cookie.
When I need the result, I get it from cookie, and attach it on axios
request.
Now, the problem is on the server side rendering, I can not get the browser cookie.
What am I gonna do with the problem?
You can store the needed info in both local storage & cookie, e.g.
import Cookie from 'js-cookie'
....
setCookie(state, value) {
if (process.client) {
localStorage.setItem('cookie', value);
}
Cookie.set('cookie', value)
}
To read it (cookies are included in the request automatically)
getCookie(context, req) {
// if server
if (req) {
if (req.headers.cookie) {
const cookie = req.headers.cookie.split(';').find(...)
}
}
// if client
if (process.client) {
const cookie = localStorage.getItem('cookie');
}
}
And to remove
removeCookie(state) {
if (process.client) {
localStorage.removeItem('cookie');
}
Cookie.remove('cookie');
}
Firstly, you can get the req (request) and res (response) from the nuxt context.
You can set a cookie via
// client side
document.cookie = 'sessionId=some-id;';
document.cookie = 'userId=awesome-id;';
// or server side
res.setHeader('Set-Cookie', ['sessionId=some-id;', 'userId=awesome-id;']);
In Nuxt 3 and Nuxt 2 Bridge you can use useCookie
Nuxt provides an SSR-friendly composable to read and write cookies.
const session = useCookie('session')
session.value = ''
I do not have much experience with flutter, what I would like to know is if there is any way to download a video of amazon s3 and save the file in the memory of the cell phone, thanks
This is the url of the video "https://s3-us-west-1.amazonaws.com/videos.ecuestre.digital/165-3745-40957-1.mp4"
This is how I downloaded a binary file in flutter :
In your pubspec.yaml, add
path_provider: ^0.2.2
includes :
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
code :
static var httpClient = new HttpClient();
Future<File> _downloadFile(String url, String filename) async {
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
}
The function consolidateHttpClientResponseBytes() comes from the flutter docs :
https://docs.flutter.io/flutter/foundation/consolidateHttpClientResponseBytes.html
Note: Edited to more concise version from Simon Lightfoot
If you are using aws resources you can use the Amplify framework to interact with your environment. This is especially helpful if you need interact with a lot of resources. Check the flutter amplify storage docs