Hopp til innhold
NorscodeNorscode

std.web

ReferanseAv Norscode-prosjektet

std.web er alt du trenger for å bygge webtjenester: lese forespørselen, sjekke tilgang, rute, og bygge svaret — rundt hundre funksjoner i én modul.

std.web er alt du trenger for å bygge webtjenester, og den største modulen i standardbiblioteket med rundt hundre funksjoner. Den dekker hele veien: lese det som kommer inn i en forespørsel — metode, sti, spørrestreng, headere, cookies og kropp — validere det, sjekke roller og tokens for tilgang, og bygge svaret som går ut. I tillegg finnes ruting, middleware, vakter og hjelpere for trygg tekst og trygge filstier.

En webtjeneste i Norscode er rett og slett funksjoner som svarer på forespørsler. Du merker en funksjon med en rute, leser det du trenger fra forespørselskonteksten ctx, og returnerer et svar. Fordi hele laget ligger i standardbiblioteket, trenger du verken et eksternt rammeverk eller en egen tjener ved siden av. Funksjonene under er ordnet etter hva du gjør med dem — begynn med familien du trenger.

Når bruker du den

Bruk std.web når du lager en HTTP-tjeneste. En rute er en funksjon som kaller web.route, leser det den trenger fra ctx med request_-funksjonene, og returnerer et svar bygget med response_. Sammen med kapabiliteten net.tcp og kommandoen nc serve har du en kjørende tjeneste.

Slik kommer du i gang

bruk std.web som web

funksjon hei(ctx: ordbok_tekst) -> ordbok_tekst {
    web.route("GET /")
    la navn = web.request_query_param(ctx, "navn")
    hvis navn == "" { navn = "verden" }
    returner web.response_builder(200, {"content-type": "text/plain; charset=utf-8"}, "Hei, " + navn + "!")
}

funksjon start() -> heiltall {
    skriv("Tjenesten er klar")
    returner 0
}

Ruta GET / besvares av funksjonen hei. Den leser en valgfri ?navn=-parameter og bygger et svar med statuskode, headere og innhold. Start tjenesten med nc serve.

Funksjonene

Lese forespørselen

Alt starter med det som kommer inn. Disse funksjonene henter de enkelte delene av forespørselen ut av ctx: hvilken metode og sti som ble brukt, spørrestrengen som helhet eller én parameter om gangen, headere, og kroppen. request_query_required er den strenge varianten som feiler tydelig hvis noe obligatorisk mangler, mens request_query_param bare gir tom tekst.

  • request_context(metode: tekst, sti: tekst, query: ordbok_tekst, headers: ordbok_tekst, body: tekst) -> ordbok_tekst — Bygger en forespørselskontekst — mest nyttig i tester.
  • request_method(ctx: ordbok_tekst) -> tekst — HTTP-metoden som ble brukt (GET, POST, …).
  • request_path(ctx: ordbok_tekst) -> tekst — Stien i forespørselen.
  • request_query(ctx: ordbok_tekst) -> ordbok_tekst — Hele spørrestrengen som en ordbok.
  • request_headers(ctx: ordbok_tekst) -> ordbok_tekst — Alle forespørsels-headere som en ordbok.
  • request_body(ctx: ordbok_tekst) -> tekst — Rå kropp i forespørselen som tekst.
  • request_params(ctx: ordbok_tekst) -> ordbok_tekst — Alle stiparametre som en ordbok.
  • request_param(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Én stiparameter som tekst.
  • request_param_int(ctx: ordbok_tekst, nøkkel: tekst) -> heltall — En stiparameter tolket som heltall.
  • request_query_param(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Verdien til én spørre-parameter, eller tom tekst.
  • request_query_required(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Som request_query_param, men feiler hvis parameteren mangler.
  • request_query_int(ctx: ordbok_tekst, nøkkel: tekst) -> heltall — En spørre-parameter tolket som heltall.
  • request_header(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Verdien til én header.
  • request_id(ctx: ordbok_tekst) -> tekst — En unik id for forespørselen, nyttig i logger.

JSON i forespørselen

Sender klienten JSON i kroppen, slipper du å tolke den selv. request_json gir hele kroppen som ordbok, og request_json_field* henter ett felt av gangen — med typede varianter for tall og boolske verdier, og _or-varianten som gir en standardverdi hvis feltet mangler.

  • request_json(ctx: ordbok_tekst) -> ordbok_tekst — Kroppen tolket som JSON-ordbok.
  • request_json_field(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Ett felt fra JSON-kroppen som tekst.
  • request_json_field_or(ctx: ordbok_tekst, nøkkel: tekst, fallback: tekst) -> tekst — Ett JSON-felt, med standardverdi hvis det mangler.
  • request_json_field_int(ctx: ordbok_tekst, nøkkel: tekst) -> heltall — Ett JSON-felt tolket som heltall.
  • request_json_field_bool(ctx: ordbok_tekst, nøkkel: tekst) -> boolsk — Ett JSON-felt tolket som boolsk.

Cookies

Cookies er hvordan en tjeneste husker en besøkende mellom forespørsler. Les dem med request_cookie (eller request_cookie_or med standardverdi), og sett dem i svaret med response_set_cookie. cookie_header bygger selve header-teksten hvis du trenger den rå.

  • request_cookie(ctx: ordbok_tekst, nøkkel: tekst) -> tekst — Verdien til én cookie.
  • request_cookie_or(ctx: ordbok_tekst, nøkkel: tekst, fallback: tekst) -> tekst — En cookie-verdi, med en oppgitt standard hvis den mangler.
  • cookie_header(nøkkel: tekst, verdi: tekst) -> tekst — Bygger teksten til en Set-Cookie-header.
  • response_set_cookie(response: ordbok_tekst, cookie: tekst) -> ordbok_tekst — Legger en cookie til i svaret.

Autentisering og roller

Beskytt ruter uten å skrive tilgangskontrollen selv. bearer_token henter tokenet fra Authorization-headeren, og require_bearer avviser forespørsler som ikke bærer det riktige. For rollebasert tilgang gir role, has_role og require_role deg henholdsvis rollen, en sjekk, og en hard sperre — og has_permission/require_permission gjør det samme for finere rettigheter.

  • auth_header(ctx: ordbok_tekst) -> tekst — Authorization-headeren rå.
  • bearer_token(ctx: ordbok_tekst) -> tekst — Bearer-token hentet fra Authorization-headeren.
  • require_bearer(ctx: ordbok_tekst, expected: tekst) -> boolsk — Sann hvis forespørselen bærer det forventede bearer-tokenet.
  • role(ctx: ordbok_tekst) -> tekst — Rollen knyttet til forespørselen.
  • has_role(ctx: ordbok_tekst, rolle: tekst) -> boolsk — Sann hvis forespørselen har den gitte rollen.
  • require_role(ctx: ordbok_tekst, rolle: tekst) -> boolsk — Krever en bestemt rolle; brukes til å beskytte ruter.
  • has_permission(ctx: ordbok_tekst, rettighet: tekst) -> boolsk — Sann hvis forespørselen har en gitt rettighet.
  • require_permission(ctx: ordbok_tekst, rettighet: tekst) -> boolsk — Krever en gitt rettighet.

Bygge svar

Når du har gjort jobben, bygger du et svar. response_builder er grunnformen: statuskode, headere og innhold. Rundt den finnes snarveier for det vanligste — response_html, response_text_plain og response_json setter riktig innholdstype for deg, response_redirect sender klienten videre, og response_file/response_static_file leverer filer. response_finalize-variantene sluttfører svaret med strenge sikkerhetsheadere.

  • response_builder(status: heltall, headers: ordbok_tekst, body: tekst) -> ordbok_tekst — Grunnformen for et svar: statuskode, headere og innhold.
  • response_status(response: ordbok_tekst) -> heltall — Leser statuskoden fra et svar.
  • response_code(response: ordbok_tekst) -> heltall — Setter statuskoden på et svar.
  • response_headers(response: ordbok_tekst) -> ordbok_tekst — Leser headerne fra et svar.
  • response_body(response: ordbok_tekst) -> tekst — Leser kroppen fra et svar.
  • response_text(response: ordbok_tekst) -> tekst — Svar med ren tekst.
  • response_with_header(response: ordbok_tekst, nøkkel: tekst, verdi: tekst) -> ordbok_tekst — Legger til én header på et svar.
  • response_html(status: heltall, body: tekst) -> ordbok_tekst — Svar med HTML og riktig innholdstype.
  • response_text_plain(status: heltall, body: tekst) -> ordbok_tekst — Svar med text/plain.
  • response_json(response: ordbok_tekst) -> ordbok_tekst — Svar med JSON og riktig innholdstype.
  • response_redirect(location: tekst, status: heltall) -> ordbok_tekst — Sender klienten videre til en annen adresse.
  • response_redirect_found(location: tekst) -> ordbok_tekst — Omdirigering med status 302.
  • response_redirect_see_other(location: tekst) -> ordbok_tekst — Omdirigering med status 303.
  • response_no_content() -> ordbok_tekst — Tomt svar med status 204.
  • response_error(status: heltall, melding: tekst) -> ordbok_tekst — Et standardisert feilsvar med gitt status.
  • response_file(sti: tekst, content_type: tekst) -> ordbok_tekst — Leverer en fil som svar.
  • response_static_file(root: tekst, rel_sti: tekst, content_type: tekst) -> ordbok_tekst — Leverer en statisk fil trygt fra en mappe.
  • response_header(response: ordbok_tekst, nøkkel: tekst) -> tekst — Leser én header fra et svar.
  • response_finalize(ctx: ordbok_tekst, response: ordbok_tekst) -> ordbok_tekst — Sluttfører svaret med standard sikkerhetsheadere.
  • response_finalize_strict(ctx: ordbok_tekst, response: ordbok_tekst) -> ordbok_tekst — Sluttfører med strenge sikkerhetsheadere.
  • response_finalize_strict_cors(ctx: ordbok_tekst, response: ordbok_tekst, tillatne_origins: tekst) -> ordbok_tekst — Sluttfører strengt, med CORS-headere.

Validering og feilsvar

God validering feiler tidlig og forklarer hvorfor. *_or_error-funksjonene henter en verdi og gir samtidig et ferdig feilsvar hvis den mangler eller har feil type, så du slipper å håndtere hvert tilfelle for hånd. validation_error_response og validation_bad_request bygger standardiserte 400-svar.

  • validation_error_body(errors: liste<tekst>) -> tekst — Bygger kroppen til et valideringsfeil-svar.
  • validation_error_response(errors: liste<tekst>, status: heiltall) -> ordbok_tekst — Et komplett 400-svar for valideringsfeil.
  • validation_bad_request(errors: liste<tekst>) -> ordbok_tekst — Et enkelt 400-svar med melding.
  • request_query_required_or_error(ctx: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> tekst
  • request_header_or_error(ctx: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> tekst
  • request_header_int_or_error(ctx: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> heiltall
  • request_header_bool_or_error(ctx: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> boolsk
  • request_json_int_or_error(payload: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> heiltall
  • request_json_text_or_error(payload: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> tekst
  • request_json_bool_or_error(payload: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> boolsk
  • request_json_list_or_error(payload: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> liste<tekst>
  • request_json_object_or_error(payload: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> ordbok_tekst
  • response_shape_validate_or_error(payload: ordbok_tekst, schema: ordbok_tekst, errors: liste<tekst>)
  • request_param_int_or_error(params: ordbok_tekst, nøkkel: tekst, errors: liste<tekst>) -> heiltall

Ruting og dispatch

Ruting knytter en sti til en funksjon. route er det du bruker i hver handler; router og subrouter lar deg organisere større tjenester. path_match, path_params og path_param tolker deler av stien, og dispatch/handle_request er maskineriet som sender en forespørsel til riktig handler — nyttig når du bygger noe utenom standardflyten.

  • route(spec: tekst) -> tekst — Registrerer hvilken metode og sti funksjonen svarer på.
  • router(prefiks: tekst) -> tekst — Oppretter en ruter for å organisere flere ruter.
  • subrouter(prefiks: tekst) -> tekst — En underruter med felles prefiks.
  • path_match(mønster: tekst, sti: tekst) -> boolsk — Sann hvis en sti matcher et mønster.
  • path_params(mønster: tekst, sti: tekst) -> ordbok_tekst — Henter navngitte deler ut av en sti.
  • route_match(spec: tekst, metode: tekst, sti: tekst) -> boolsk — Matcher en forespørsel mot en rute.
  • path_param(params: ordbok_tekst, nøkkel: tekst) -> tekst — Én navngitt del av stien.
  • path_param_or(params: ordbok_tekst, nøkkel: tekst, fallback: tekst) -> tekst — En stidel, med standardverdi hvis den mangler.
  • dispatch(routes: ordbok_tekst, metode: tekst, sti: tekst) -> tekst — Sender en forespørsel til riktig handler.
  • dispatch_params(routes: ordbok_tekst, metode: tekst, sti: tekst) -> ordbok_tekst — Som dispatch, med stiparametre.
  • handle_request(ctx: ordbok_tekst) -> ordbok_tekst — Håndterer en hel forespørsel gjennom ruteren.

Middleware, vakter og livssyklus

Middleware kjører før eller etter hver forespørsel — logging, måling, felles headere — uten å gjenta koden i hver rute. guard og use_guard legger en sperre foran ruter, dependency/use_dependency gir delte ressurser (som en databasetilkobling) til handlerne, og startup/shutdown-krokene kjører kode når tjenesten starter og stopper.

  • guard() -> tekst — Definerer en sperre som kan legges foran ruter.
  • use_guard(navn: tekst) -> tekst — Aktiverer en sperre for ruter.
  • dependency(navn: tekst) -> tekst — Definerer en delt ressurs handlerne kan få.
  • use_dependency(navn: tekst) -> tekst — Henter en delt ressurs i en handler.
  • request_dependency(ctx: ordbok_tekst, nøkkel: tekst) -> ordbok_tekst — Henter en avhengighet knyttet til forespørselen.
  • request_middleware() -> tekst — Kode som kjører før hver forespørsel.
  • response_middleware() -> tekst — Kode som kjører etter hvert svar.
  • error_middleware() -> tekst — Kode som kjører når en handler feiler.
  • startup_hook() -> tekst — Registrerer kode som kjører ved oppstart.
  • shutdown_hook() -> tekst — Registrerer kode som kjører ved nedstenging.
  • startup() -> heltall — Kjører oppstartskrokene.
  • shutdown() -> heltall — Kjører nedstengingskrokene.

Trygg tekst og stier

Alt som kommer utenfra kan være fiendtlig. escape_html gjør brukertekst trygg å vise i HTML, og safe_filename, safe_slug, safe_path_segment, safe_relative_path og safe_join_path sørger for at et filnavn eller en sti fra en bruker aldri kan peke utenfor der du vil.

  • escape_html(tekst_verdi: tekst) -> tekst — Gjør tekst trygg å vise i HTML.
  • safe_filename(tekst_verdi: tekst) -> tekst — Renser et filnavn fra brukeren.
  • safe_path_segment(tekst_verdi: tekst) -> tekst — Renser én del av en sti.
  • safe_slug(tekst_verdi: tekst) -> tekst — Lager en trygg slug av tekst.
  • safe_relative_path(rel_sti: tekst) -> boolsk — Sann hvis en relativ sti holder seg innenfor roten.
  • safe_join_path(root: tekst, rel_sti: tekst) -> tekst — Setter sammen en sti uten å kunne peke utenfor roten.

Dokumentasjon og server

openapi_json og docs_html genererer maskinlesbar og menneskelesbar dokumentasjon av rutene dine, og web_server_start starter tjeneren når du ikke bruker nc serve direkte.

  • openapi_json(tittel: tekst, versjon: tekst) -> tekst — Genererer OpenAPI-beskrivelse av rutene.
  • docs_html(tittel: tekst, versjon: tekst) -> tekst — Genererer lesbar dokumentasjon av rutene.
  • web_server_start(ruter: liste<tekst>, vert: tekst, port: heltall) -> heltall — Starter webtjeneren programmatisk.

Godt å vite

  • Hver rute er en egen funksjon som kaller web.route — kjøretiden har ingen dynamiske sti-ruter, så én funksjon per fast sti; bruk spørreparametre for variasjon.
  • Les alltid brukerdata gjennom request_-funksjonene og bygg svar med response_; da slipper du å håndtere HTTP-detaljene selv.
  • Bruk require_role/require_bearer for å beskytte ruter, escape_html før du viser brukertekst, og husk at tjenesten trenger net.tcp for å binde en port.

std.web er én av modulene i standardbiblioteket. Alt følger med kjøretiden — ingen installasjon, ingen eksterne avhengigheter. Se også Dokumentasjon for språket og kjøretiden.

Les også

Tilbake til oversikten