Streamline routing

- put openapi doc behind `api/doc` instead of `app/doc`
- don't require `index.html` for the webapp
This commit is contained in:
Eike Kettner 2019-12-30 21:59:06 +01:00
parent fc3e22e399
commit b15b9cc217
8 changed files with 33 additions and 21 deletions

View File

@ -45,7 +45,7 @@ server. If it is deployed at `http://localhost:7880`, then check this
url: url:
``` ```
http://localhost:7880/app/doc http://localhost:7880/api/doc
``` ```
## Examples ## Examples

View File

@ -150,8 +150,8 @@ $ ./docspell-joex*/bin/docspell-joex /path/to/joex-config.conf
``` ```
After starting the rest server, you can reach the web application at After starting the rest server, you can reach the web application at
path `/app/index.html`, so using default values it would be path `/app`, so using default values it would be
`http://localhost:7880/app/index.html`. `http://localhost:7880/app`.
You should be able to create a new account and sign in. Check the You should be able to create a new account and sign in. Check the
[configuration page](configure.html) to further customize docspell. [configuration page](configure.html) to further customize docspell.

View File

@ -53,7 +53,7 @@ Example screenshot:
This example shows a source with name "test". It defines two urls: This example shows a source with name "test". It defines two urls:
- `/app/index.html#/upload/<id>` - `/app#/upload/<id>`
- `/api/v1/open/upload/item/<id>` - `/api/v1/open/upload/item/<id>`
The first points to a web page where everyone could upload files into The first points to a web page where everyone could upload files into

View File

@ -42,7 +42,7 @@ really required, but improves OCR.
$ ./docspell-joex*/bin/docspell-joex $ ./docspell-joex*/bin/docspell-joex
``` ```
in the other. in the other.
4. Point your browser to: <http://localhost:7880/app/index.html> 4. Point your browser to: <http://localhost:7880/app>
5. Register a new account, sign in and try it. 5. Register a new account, sign in and try it.
Check the [documentation](doc.html) for more information on how to use Check the [documentation](doc.html) for more information on how to use

View File

@ -22,17 +22,18 @@ object RestServer {
blocker: Blocker blocker: Blocker
)(implicit T: Timer[F], CS: ContextShift[F]): Stream[F, Nothing] = { )(implicit T: Timer[F], CS: ContextShift[F]): Stream[F, Nothing] = {
val templates = TemplateRoutes[F](blocker, cfg)
val app = for { val app = for {
restApp <- RestAppImpl.create[F](cfg, connectEC, httpClientEc, blocker) restApp <- RestAppImpl.create[F](cfg, connectEC, httpClientEc, blocker)
httpApp = Router( httpApp = Router(
"/api/info" -> routes.InfoRoutes(), "/api/info" -> routes.InfoRoutes(),
"/api/v1/open/" -> openRoutes(cfg, restApp), "/api/v1/open/" -> openRoutes(cfg, restApp),
"/api/v1/sec/" -> Authenticate(restApp.backend.login, cfg.auth) { token => "/api/v1/sec/" -> Authenticate(restApp.backend.login, cfg.auth) { token =>
securedRoutes(cfg, restApp, token) securedRoutes(cfg, restApp, token)
}, },
"/api/doc" -> templates.doc,
"/app/assets" -> WebjarRoutes.appRoutes[F](blocker), "/app/assets" -> WebjarRoutes.appRoutes[F](blocker),
"/app" -> TemplateRoutes[F](blocker, cfg) "/app" -> templates.app
).orNotFound ).orNotFound
finalHttpApp = Logger.httpApp(logHeaders = false, logBody = false)(httpApp) finalHttpApp = Logger.httpApp(logHeaders = false, logBody = false)(httpApp)

View File

@ -21,7 +21,7 @@ object Flags {
cfg.appName, cfg.appName,
cfg.baseUrl, cfg.baseUrl,
cfg.backend.signup.mode, cfg.backend.signup.mode,
s"assets/docspell-webapp/${BuildInfo.version}" s"/app/assets/docspell-webapp/${BuildInfo.version}"
) )
implicit val jsonEncoder: Encoder[Flags] = implicit val jsonEncoder: Encoder[Flags] =

View File

@ -21,25 +21,36 @@ object TemplateRoutes {
val `text/html` = new MediaType("text", "html") val `text/html` = new MediaType("text", "html")
trait InnerRoutes[F[_]] {
def doc: HttpRoutes[F]
def app: HttpRoutes[F]
}
def apply[F[_]: Effect](blocker: Blocker, cfg: Config)( def apply[F[_]: Effect](blocker: Blocker, cfg: Config)(
implicit C: ContextShift[F] implicit C: ContextShift[F]
): HttpRoutes[F] = { ): InnerRoutes[F] = {
val indexTemplate = memo(loadResource("/index.html").flatMap(loadTemplate(_, blocker))) val indexTemplate = memo(loadResource("/index.html").flatMap(loadTemplate(_, blocker)))
val docTemplate = memo(loadResource("/doc.html").flatMap(loadTemplate(_, blocker))) val docTemplate = memo(loadResource("/doc.html").flatMap(loadTemplate(_, blocker)))
val dsl = new Http4sDsl[F] {} val dsl = new Http4sDsl[F] {}
import dsl._ import dsl._
HttpRoutes.of[F] { new InnerRoutes[F] {
case GET -> Root / "index.html" => def doc =
for { HttpRoutes.of[F] {
templ <- indexTemplate case GET -> Root =>
resp <- Ok(IndexData(cfg).render(templ), `Content-Type`(`text/html`)) for {
} yield resp templ <- docTemplate
case GET -> Root / "doc" => resp <- Ok(DocData().render(templ), `Content-Type`(`text/html`))
for { } yield resp
templ <- docTemplate }
resp <- Ok(DocData().render(templ), `Content-Type`(`text/html`)) def app =
} yield resp HttpRoutes.of[F] {
case GET -> _ =>
for {
templ <- indexTemplate
resp <- Ok(IndexData(cfg).render(templ), `Content-Type`(`text/html`))
} yield resp
}
} }
} }

View File

@ -196,7 +196,7 @@ urlInfoMessage flags model =
, dd [] , dd []
[ let [ let
url = url =
flags.config.baseUrl ++ "/app/index.html#/upload/" ++ model.source.id flags.config.baseUrl ++ "/app#/upload/" ++ model.source.id
in in
a [ href url, target "_blank" ] [ code [] [ text url ] ] a [ href url, target "_blank" ] [ code [] [ text url ] ]
] ]