REST APIκ° 404 μλ΅μ μ¬μ©νμ¬ λ μ½λκ° μ‘΄μ¬νμ§ μμμ λνλ΄λ κ²μ λ§€μ° μΌλ°μ μ
λλ€. λ°λ‘ μ§κΈ μ΄λ° μΌμ΄ λ°μνλ©΄ κ²°κ³Όλ networkError
μ΄λ©°, μ΄λ κΈ°λ³Έμ μΌλ‘ Apollo μ€νμ μν΄ GraphQL μ€λ₯λ³΄λ€ λ μΉλͺ
μ μΈ μ€λ₯λ‘ μ²λ¦¬λλ κ²μΌλ‘ 보μ
λλ€.
μλ₯Ό λ€μ΄ λ€μκ³Ό κ°μ 쿼리λ₯Ό μ¬μ©ν©λλ€.
query BookQuery($slug: ID!) {
book(slug: $slug) @rest(type: "Book", path: "book/:slug") {
name
author
}
}
μλ ν¬μΈνΈκ° 404λ₯Ό λ°ννλ©΄ μλκ° error
render propμ μ¬μ©νμ¬ μ¬μ©μμκ² μΉλͺ
μ μ΄μ§ μμ μ€λ₯ λ©μμ§λ₯Ό νμ ν κ°λ₯μ±μ΄μλ κ²½μ° μ²λ¦¬ν΄μΌνλ λ€νΈμν¬ μ€λ₯μ ν¨κ» κ±°λΆλ©λλ€. μ¦, μ΄κ²μ΄ REST λμ GraphQL 쿼리 μΈ κ²½μ° λ€νΈμν¬ μ€λ₯λ‘ λΆλ₯λμ§ μμΌλ©° μ΄λ¬ν λ°©μμΌλ‘ μ²λ¦¬λ©λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ 404 λ€νΈμν¬ μ€λ₯λ₯Ό GraphQL μ€λ₯λ‘ λ³ννλ λ΄ μ¬μ©μ μ§μ error-link
κ²μ¬λ₯Ό μΆκ°νμ΅λλ€.
forward(operation).subscribe({
next: result => {...},
error: networkError => {
if (networkError.statusCode === 404) {
return observer.next({errors: [networkError]});
}
//...
observer.error(networkError);
},
complete: observer.complete.bind(observer),
});
μ¬μ ν κ°μ μ μ¬μ§κ° μμ§λ§ λ¬Έμ λ₯Ό ν΄κ²°ν©λλ€.
λλ μ΄κ²μ΄ apollo-link-rest
μμ μ΄λ»κ² λ ν΄κ²°λμ΄μΌνλμ§ κΆκΈν΄μ λνλ₯Ό μμν κ²μ΄λΌκ³ μκ°νμ΅λλ€.
μ’μ μ§λ¬Έμ λλ€. -μ΄ ν¨ν΄μ΄ λ¬Έμμ λν μ μμΌλ‘ μΆκ°λκΈ°λ₯Ό λ°λλλ€. λλ μ¬λ¬ μν΄λ‘ λ§ν¬κ° κ²ͺλ λ¬Έμ μ μ’ λ₯λΌκ³ μκ°ν©λλ€ (μν΄λ‘ λ§ν¬ μνκ° λ μ€λ¦ λλ€).
κ·Έλ¬λ μ΄κ²μ΄ ApolloLinkμ λͺ¨λ μ¬μ©μμκ² λ§λ λ΅μ΄λΌκ³ νμ ν μλ μμ΅λκΉ?
μ΄κ²μ νμ¬ λͺ¨λ http μ€λ₯κ° apollo-link-restμμ μ²λ¦¬λλ λ°©λ²μ λλ€.
if (res.status >= 300) {
// Throw a JSError, that will be available under the
// "Network error" category in apollo-link-error
let parsed: any;
try {
parsed = await res.json();
} catch (error) {
// its not json
parsed = await res.text();
}
rethrowServerSideError(
res,
parsed,
`Response not successful: Received status code ${res.status}`,
);
}
return res;
μ¬μ©μκ° μ€λ₯ μ²λ¦¬ λ°©λ²μ μ§μ ν μμλ λμ λ¬Έμ μΌμΉ κΈ°λ₯μ μΆκ° ν μ μμ΅λκΉ?
404 == null
μ κ°μ μΌλ°μ μΈ κ²½μ°μ μ μ©ν κΈ°λ³Έ μ νΈλ¦¬ν°λ₯Ό μ 곡 ν μ μμ΅λλ€.
μ°λ¦¬κ° μκ°νλ μ루μ μ΄μ΄ λ§ν¬μ λͺ¨λ μ¬μ©μμκ² μ ν©νμ§ μμ μ μλ€λ @fbartho μ μ°λ €λ₯Ό 곡μ νλ λμ 404 μ€λ₯κ° νΉν ν΄λ‘μ΄ κ²½μ°λ₯Ό μκ°νμ΅λλ€. ν μ€νΈμμμ΄ μλ₯Ό μ·¨νλ©΄ :
query postAndTags {
post @rest(type: "Post", path: "/post/1") {
id
title
}
tags @rest(type: "[Tag]", path: "/tags") {
name
}
}
post
κ° μ‘΄μ¬νμ§ μκ³ 404λ₯Ό λ°ννλ©΄ μ 체 μΏΌλ¦¬κ° λ€νΈμν¬ μ€λ₯λ‘ μ€ν¨ν©λλ€. μ΄λ€ κ²½μ°μλ μ΄κ²μ΄ λ°λμ§ ν μ μμ§λ§ κ²°κ³Όλ λ€μκ³Ό κ°μμΌν©λλ€.
const data = {
post: null,
tags: [{ name: 'apollo' }, { name: 'graphql' }],
}
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ €λ©΄ @paulpdanielsκ° μ μνλλ‘ μΆκ° μ€λ₯ μ²λ¦¬λ₯Ό μΆκ°νλ κ²μ΄ λ§€μ° μ½μ΅λλ€. 4xx μ€λ₯λ₯Ό μ΄ν΄λ³΄λ©΄ GraphQL μ€λ₯ λλ κ²°κ³Όλ₯Ό null
μ€μ νλ λ± νΉμ μ²λ¦¬κ° νμν μΉλͺ
μ μ΄μ§ μμ μ€λ₯ μΌ κ°λ₯μ±μ΄μλ 404 λ° 400/412/422 (λ³μ΄) λ§ μ€μ λ‘ λ³Ό μ μμ΅λλ€.
μ΄λ¬ν μ€λ₯μ λν΄ κ³ μ λ μ²λ¦¬κΈ°λ₯Ό μ 곡νλ κ²μ΄ ν©λ¦¬μ μΈμ§ μλλ©΄ error-link
λλ μμ© νλ‘κ·Έλ¨μ 맑겨μΌνλμ§μ λν μλ¬Έμ΄ λ¨μ μμ΅λλ€. μ¬λ¬ λ³ν μΏΌλ¦¬κ° μ§μλμ§ μκΈ° λλ¬Έμ (λ΄ μκ°μ?) νΉν κ΄λ ¨μ±μ΄μλ μ μΌν νμ¬ μ§§μ κ²μ μμμ μμν 404 μμ μ
λλ€.
ꡬμ±μ μ€λ₯ μ²λ¦¬κΈ°λ₯Ό μΆκ°νλ μ΅μ
λ μμ§λ§ μ€μ λ‘λ κ±°κΈ°μ μνλ error-link
μμ κΈ°λ₯μ νμΉλ κ²μ²λΌ 보μ
λλ€. λνμ΄ λ§ν¬μ APIλ₯Ό λΆνμνκ² λ³΅μ‘νκ² λ§λ€ μλ μμ΅λλ€.
@marnusw νλ₯ν μλ΅μ λλ€. κΈ°λ³Έμ μΌλ‘ κ·νμ νλμ ꡬννλ μμ μ μ§μν©λλ€!
μ’μ REST API κ΄νκ³Ό μΌμΉνλλ‘ 404λ₯Ό μ μμ μΈ λ€νΈμν¬ μ€λ₯λ‘ λ³΅μνλ PRμ μ¬λ Έμ΅λλ€. https://github.com/apollographql/apollo-link-rest/pull/283
@christrude REST APIμ κ΄ν΄μλ λμνμ§ μμ§λ§μ΄ λΌμ΄λΈλ¬λ¦¬μ λͺ©μ μ REST APIκ° GraphQLμ²λΌ μλνλλ‘ λ§λλ κ²μ
λλ€. λ°λΌμ λλ½ λ 리μμ€μ λν GraphQL μ κ·Ό λ°©μμ΄ null
λ₯Ό λ°ννλ κ²μ΄λΌλ©΄μ΄ λΌμ΄λΈλ¬λ¦¬λ RESTful 404 κ·μΉμ GraphQL null
λ°ν κ° κ·μΉμΌλ‘ λ³νν΄μΌν©λλ€.
@christrude REST APIμ κ΄ν΄μλ λμνμ§ μμ§λ§μ΄ λΌμ΄λΈλ¬λ¦¬μ λͺ©μ μ REST APIκ° GraphQLμ²λΌ μλνλλ‘ λ§λλ κ²μ λλ€. λ°λΌμ λλ½ λ 리μμ€μ λν GraphQL μ κ·Ό λ°©μμ΄
null
λ₯Ό λ°ννλ κ²μ΄λΌλ©΄μ΄ λΌμ΄λΈλ¬λ¦¬λ RESTful 404 κ·μΉμ GraphQLnull
λ°ν κ° κ·μΉμΌλ‘ λ³νν΄μΌν©λλ€.
κ·Έλ λ€λ©΄ GraphQLμ UIμμ 404 μλ΅μ μ΄λ»κ² μ²λ¦¬ ν κ²μ μ μν©λκΉ? μ무κ²λνμ§ λ§μΈμ? κ·Έλμ μμ²μ μ‘°μ©ν μ£½μκΉμ? κ·Έκ²μ μμ²λκ² λμκ±°λ μ’μ§ μμ UX / api κ΄λ¦¬μ λλ€.
IDλ‘ νλͺ©μ 쿼리νκ³ nullμ λ°ννλ©΄ κ·Έμ λ°λΌ UIμμ μ²λ¦¬ν©λλ€. λ°μ΄ν°κ° ν¬ν¨ λ κ²½μ° νμν©λλ€.
μ¬κΈ° @marnuswμ λμν©λλ€. μ¬μ©μμ λλ¨Έμ§ APIκ° μννλ μμ μ μ€μ λ‘ μ μ΄ ν μ μμΌλ―λ‘ λΌμ΄λΈλ¬λ¦¬κ° νμ©νλ μμ μ΄ μ§λμΉκ² μ νλμ§ μμμΌν©λλ€. 404 => null 맀νμ μλμ μΌλ‘ μ§κ΄μ μΈ μλ―Έ 체κ³λ‘ RESTμ μμ² λͺ¨λΈ λΉ λ¨μΌ 리μμ€μμ GraphQLμ μμ² λΉ λ€μ€ 리μμ€ (ν΄λΌμ΄μΈνΈ κ΄μ μμ)λ‘ μ΄λν μμλ λμμ λλ½ λ λ°μ΄ν°κ° νλ°νμ§ μμ΅λλ€.
μλ΅ λ³νκΈ°μ μ¬μ ν¨ν€μ§ λ²μ μ΄λ μ¬μ©μκ° http μν μ²λ¦¬λ₯Ό μμ ν μ μ΄ ν μμλ μμ² μ²λ¦¬ λ Όλ¦¬μ μΆμνμ κ°μ΄μ΄ λμμ μ΅νΈ μμνλ λ μ’μ λ°©λ²μ΄μμ μ μμ΅λλ€. κ·Έλ¬λ λλ μ΄μ νλμΌλ‘ λ λ리λ κ²μ΄ μ¬λ°λ₯Έ μ κ·Όμ΄λΌκ³ μκ°νμ§ μμ΅λλ€.
μ κ·Ό λ°©μμ λ¬Έμ μ€ μΌλΆλ κ²°κ³Ό ꡬλ μμ 404μ΄κΈ° λλ¬Έμ null κ²°κ³ΌμΈμ§ λλ μ½ν μΈ μμ λ°ν 201 λλ μ΄μ μ μ¬ν κ²μΈμ§ μ μ μλ€λ κ²μ λλ€. μ νν°μ¨μ΄μμμ΄ λ¬Έμ λ₯Ό μμ νμ¬ μνλ₯Ό νμΈνκ³ μ€μ μλ² μ€λ₯ λ©μμ§μ μ‘μΈμ€ ν μ μκΈ° λλ¬Έμ λ¬Έμ λ₯Ό κ°μ νλ μ€λ₯λ₯Ό λ°μ μν€λλ‘νμ΅λλ€. νΉν μ κ²½μ°μλ μ¬μ©μ μ§μ κ°μ Έ μ€κΈ°λ₯Ό μ¬μ©νμ¬ μΈμ¦ ν ν°μ μ£Όμ νκΈ° λλ¬Έμ λλ€. , κ·Έλ¦¬κ³ apolloκ° κ·Έκ²μ μμ νκΈ° μ μ μλ΅μ μ»λ λ° μ¬μ©ν μ μμ΅λλ€. λ΄ μ루μ μ ν κ°μ§ κ²½μ°λ₯Ό μ μΈνκ³ μ± μ 체μμ λ€λ₯Έ 404 μλ΅μ λν λμ λ΄μμ λλ€.